Кошмар импорта C # DLL в MQL5

Привет всем, у меня небольшая проблема, я программирую в основном на python, и на самом деле прошло некоторое время с тех пор, как я кодировал на C # и время от времени кодировал mql. Моя проблема в том, что я создал dll-файл C #, который имеет несколько простых функций:

[DllExport("debugger", CallingConvention = CallingConvention.StdCall)]
[return: MarshalAs(UnmanagedType.LPWStr)]
public static string debugger()
{
        return "Send help!! SOS";
}

[DllExport("debugger2", CallingConvention = CallingConvention.StdCall)]
public static int debugger2()
{
        return 12345;
}

Это мой простой код из моего файла C #, он находится внутри общедоступного статического класса, а платформа решения - x64. Код компилируется нормально, и я не нахожу проблем. Вот так выглядит мой код MetaEditor:

#import "simpleFunctions.dll"
        string debugger();

        int debugger2();
#import

int OnInit()
{
        //Print a statement just to show where code crashes
        Print("We are definitly in it :D");

        Print(debugger);
}

Судя по тому, что мне сообщает журнал, все работает нормально, файл добавляется из библиотек, а также выполняется инструкция печати в начале функции OnInit. Проблема возникает при вызове первой функции отладчика из моего файла dll, чуть ниже моего оператора печати в журнале, я получаю следующие ошибки:

- Cannot find 'debugger', in 'simpleFunctions.dll' - unresolved import function call - OnInit critical error - tester stopped because OnInit failed

Я поискал по всему Интернету, к моему неудовольствию, обнаружив, что на самом деле никто не дает практического ответа на этот вопрос. Я подозреваю, что ошибка, возможно, кроется в C # стороне вещей в отношении различий в типах данных, но я действительно не знаю, где продолжить изучение этой точки. Любая помощь будет принята с благодарностью.


person Thembekile Mkhombo    schedule 17.05.2020    source источник
comment
Returnjng такая строка вряд ли закончится хорошо. Если хост-программы не знают, как освободить строку, которая была выделена в куче COM. Сообщение об ошибке сообщает вам, что не существует экспортированной функции с таким именем. Используйте dumpbin, чтобы проверить это.   -  person David Heffernan    schedule 17.05.2020
comment
свалка ?? Извините, я не совсем понимаю, что это такое, вы можете уточнить?   -  person Thembekile Mkhombo    schedule 17.05.2020
comment
Введите это слово в поисковую систему   -  person David Heffernan    schedule 17.05.2020


Ответы (1)


Ну, после поиска, вероятно, каждого веб-сайта для ответа на мой вопрос, переключения обратно на python и попытки другого способа подключения к mql5 (с использованием сокетов), чем, наконец, попытки C ++ и потратить последние два дня на изучение этого, я думаю, что наконец решил моя проблема. Публикуйте это только для того, чтобы помочь тем, у кого может быть аналогичная проблема в будущем. Я подумал, что, поскольку MQL5 больше похож на C ++, чем на C #, процесс компоновки будет немного проще. Сам код был совсем несложным, потому что я просто пытался получить функции, работающие на MQL5, из C ++.

#include "pch.h"
#include "CPPMQLSQLConnector.h"
#define CPPMQLSQLCONNECTOR_API
#include <string>

std::string __stdcall myString(std::string Words)
{
    static std::string myWords = "This is about to work I can feel it. ";
    return myWords + Words;
}

int __stdcall myInt(int numbr)
{
    static int myNumber = 1998;
    numbr = 22;
    return myNumber + numbr;
}

Обратите внимание на __stdcall перед указателем метода. Соглашение о вызове необходимо, чтобы MQL5 знал, как получить функции из библиотеки.

В моем заголовочном файле C ++ я сообщаю C ++, какие функции я хочу экспортировать, используя '__declspec (dllexport)' и '__declspec (dllimport)', мое мнение по этому вопросу стоит столько же, сколько вы за него заплатили, но я понимаю что ключевое слово export позволяет C ++ знать, какие функции я хотел бы экспортировать, а ключевое слово import используется MQL5 или любым другим приложением, чтобы знать, какие функции импортировать. Мой заголовочный файл

#pragma once
#include <string>

#ifndef MYDLL
    #define MYDLL

    #ifdef CPPMQLSQLCONNECTOR_API 
        extern "C" __declspec(dllexport) std::string __stdcall myString(std::string Words);
        extern "C" __declspec(dllexport) int __stdcall myInt(int numbr); 

    #else
        extern "C" __declspec(dllimport) std::string __stdcall myString(std::string Words);
        extern "C" __declspec(dllimport) int __stdcall myInt(int numbr);

    #endif

#endif

Мы используем ключевое слово extern «C», чтобы компилятор знал, что он должен ожидать код «C».

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

#import "CPPMQLSQLConnector.dll"
    string myString(string s);

    int myInt(int i);
#import

int OnInit()
{
    string Word = "Momma I made it!!!!!!!!!!!!";
    int numbr = 25;

    Print("We definitely init ;D");

    Print("La string:   ", myString(Word));
    Print("La integer:   ", myInt(numbr));

    return(INIT_SUCCEEDED);
}

person Thembekile Mkhombo    schedule 20.05.2020