Как импортировать функцию класса из dll файла?

 

Я пытаюсь разобраться с написанием dll для mt5 и написал простенькую dll.

dllmain.cpp

// dllmain.cpp : Defines the entry point for the DLL application.
#include "stdafx.h"
#include "Header1.h"

int iParam;

BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
                     )
{
    switch (ul_reason_for_call)
    {
    case DLL_PROCESS_ATTACH:
        iParam = 7;
        break;
    case DLL_THREAD_ATTACH:
        iParam += 1;
        break;
    case DLL_THREAD_DETACH:
    case DLL_PROCESS_DETACH:
        break;
    }
    return TRUE;
}

const int GetSomeParam() {
    return iParam;
}

Project2.cpp

// Project2.cpp : Defines the exported functions for the DLL application.
//

#include "stdafx.h"
#include "Project2.h"
#include "Header1.h"

PROJECT2_API int printing_f() {
    return 1000;
}

PROJECT2_API int xyz::printing_class() {
    return 2000;
}

Project2.h

// The following ifdef block is the standard way of creating macros which make exporting
// from a DLL simpler. All files within this DLL are compiled with the PROJECT2_EXPORTS
// symbol defined on the command line. This symbol should not be defined on any project
// that uses this DLL. This way any other project whose source files include this file see
// PROJECT2_API functions as being imported from a DLL, whereas this DLL sees symbols
// defined with this macro as being exported.
#ifdef PROJECT2_EXPORTS
#define PROJECT2_API /*extern "C"*/ __declspec(dllexport)
#else
#define PROJECT2_API __declspec(dllimport)
#endif
PROJECT2_API void printing_f(char* pChar);

class xyz
{
private:
    int abc;
public:
    PROJECT2_API int printing_class();
};

Собственно тут все просто, есть простая функция printing_f - которая является простой импортируемой функцией, и метод класса который я хочу вызывать из dll printing_class.


В mql5 я пытаюсь вызвать их так


#import "Project2.dll"
int printing_f();
int printing_class();
#import



//+------------------------------------------------------------------+
//|                                                                  |
//+------------------------------------------------------------------+
void OnStart()
  {

   printing_f();
   printing_class();
  }
//+------------------------------------------------------------------+


Первая функция вызывается успешно, а вот при вызове второй происходит ошибка 

Cannot find 'printing_class' in 'Project2.dll'

unresolved import function call

Собственно как мне в MQL5 вызвать функцию из класса?

 

Забыл совсем, пример проекта, и собранная dll ка - для быстрого воспроизведения

 

Собственно как мне в MQL5 вызвать функцию из класса?

методы класса вызываются через функции :-)

////////////// C++

class MyClass {
public:
        MyClass() {};
       ~MyClass() {};
        int method_A(int arg) { return arg+2; };
} ; 
// экспортируемые функции, дёргают методы класса
MyClass *MyClass_New() { return MyClass.new(); }
void MyClass_Delete(MyClass *instance) { delete instance; }
int MyClass_method_A(MyClass *instance, int arg) {
    if (instance) return instance.method_A(arg);
    return -1;
}

///////////////////////  MQL

// импортируем функции
#import MyClass.dll
int MyClass_New();
void MyClass_Delete(int);
int MyClass_method_A(int,int);
#import

// пишем класс
class MyClass {
        int instance; // c++ object
public:
        MyClass() { instance=MyClass_New(); };
        ~MyClass() { MyClass_Delete(instance); };
        int method_A(int arg) { return MyClass_method_A(instance,arg); }
};

это "с руки", считайте псевдокодом..

 
Maxim Kuznetsov:

методы класса вызываются через функции :-)

это "с руки", считайте псевдокодом..

Мне кажется тип инстанса int, будет не корректный в 64 битной системе, для указателей и хендлов.
Как то тоже нарывался на это. Правильней long делать.  

 

кстати, очень полезная штука - консолька для отладки

открывает дополнительное окошко и перенаправляет туда стандартные потоки stdin stderr

// reopen windows console
// copy-paste from https://progi.pro/otkritie-konsoli-windows-dlya-stdinstdoutstderr-dlya-win32-i-win64-v-c-10578783
#include <io.h>
#include <stdio.h>
#include <fcntl.h>
#include <Windows.h>
MTAPI(int) console() {
    int fdStd;
    HANDLE hStd;
    CONSOLE_SCREEN_BUFFER_INFO coninfo;
    /* ensure references to current console are flushed and closed
     * before freeing the console. To get things set up in case we're
     * not a console application, first re-open the std streams to
     * NUL with no buffering, and close invalid file descriptors
     * 0, 1, and 2. The std streams will be redirected to the console
     * once it created. */
    if (_get_osfhandle(0) < 0)
        _close(0);
    freopen("//./NUL", "r", stdin);
    setvbuf(stdin, NULL, _IONBF, 0);
    if (_get_osfhandle(1) < 0)
        _close(1);
    freopen("//./NUL", "w", stdout);
    setvbuf(stdout, NULL, _IONBF, 0);
    if (_get_osfhandle(2) < 0)
        _close(2);
    freopen("//./NUL", "w", stderr);
    setvbuf(stderr, NULL, _IONBF, 0);

    FreeConsole();

    if (!AllocConsole()) {
        //ERROR_WINDOW("Cannot allocate windows console!");
        return 1;
    }
    SetConsoleTitle("My Nice Console");

    // set the screen buffer to be big enough to let us scroll text
    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &coninfo);
    coninfo.dwSize.Y = 1024;
    //coninfo.dwSize.X = 100;
    SetConsoleScreenBufferSize(GetStdHandle(STD_OUTPUT_HANDLE), coninfo.dwSize);

    // redirect unbuffered STDIN to the console
    hStd = GetStdHandle(STD_INPUT_HANDLE);
    fdStd = _open_osfhandle((intptr_t)hStd, _O_TEXT);
    _dup2(fdStd, fileno(stdin));
    SetStdHandle(STD_INPUT_HANDLE, (HANDLE)_get_osfhandle(fileno(stdin)));
    _close(fdStd);

    // redirect unbuffered STDOUT to the console
    hStd = GetStdHandle(STD_OUTPUT_HANDLE);
    fdStd = _open_osfhandle((intptr_t)hStd, _O_TEXT);
    _dup2(fdStd, fileno(stdout));
    SetStdHandle(STD_OUTPUT_HANDLE, (HANDLE)_get_osfhandle(fileno(stdout)));
    _close(fdStd);

    // redirect unbuffered STDERR to the console
    hStd = GetStdHandle(STD_ERROR_HANDLE);
    fdStd = _open_osfhandle((intptr_t)hStd, _O_TEXT);
    _dup2(fdStd, fileno(stderr));
    SetStdHandle(STD_ERROR_HANDLE, (HANDLE)_get_osfhandle(fileno(stderr)));
    _close(fdStd);

    // Set Con Attributes
    SetConsoleTextAttribute(GetStdHandle(STD_OUTPUT_HANDLE),
        FOREGROUND_GREEN | FOREGROUND_INTENSITY);
    SetConsoleMode(GetStdHandle(STD_OUTPUT_HANDLE),
        ENABLE_PROCESSED_OUTPUT | ENABLE_WRAP_AT_EOL_OUTPUT);
    SetConsoleMode(GetStdHandle(STD_INPUT_HANDLE),
        ENABLE_ECHO_INPUT | ENABLE_LINE_INPUT);
        printf("console open for stdout\n");
        fprintf(stderr,"console open for stderr\n");
        return 0;
}

при отладке DLL штука просто незаменимая

 
.def файл есть в проекте?
Причина обращения: