MQL4 C ++ Dll изменить строковый аргумент в вызове функции

Вот мой код для MetaTraderWrapper.dll:

#define MT4_EXPFUNC __declspec(dllexport)

MT4_EXPFUNC void __stdcall PopMessageString(wchar_t *message)
{
auto result = L"Hello world !";
int  n      = wcslen( result );
wcscpy_s( message, n + 1, result );
}

На стороне MQL4-Caller используется этот скрипт:

#property strict
#import "MetaTraderWrapper.dll"int PopMessageString( string & );
#import
//
void OnStart(){
string message;
if (  StringInit( message, 64 ) ){
PopMessageString(  message );
int n = StringLen( message );
MessageBox(        message );
}
}

Таким образом, это работает, когда message были правильно инициализированы с StringInit() функция и достаточно памяти было выделено.

Что мне нужно сделать, это выделить message переменная не в скрипте MQL4, а внутри DLL.

В функции c ++ должно быть что-то вроде этого:

MT4_EXPFUNC void __stdcall PopMessageString(wchar_t *message)
{
auto result = L"Hello world !";
int  n      = wcslen( result );

// allocate here, but does not work
message = new wchar_t[n + 1];        // <--------- DOES NOT WORK
//
wcscpy_s( message, n + 1, result );
}

Что я могу сделать ?

0

Решение

Познакомьтесь с Wild Worlds из MQL4:
Шаг 1: забыть string быть string ( это struct … с 2014 года)

Внутреннее представление строкового типа представляет собой структуру длиной 12 байтов:

#pragma pack(push,1)
struct MqlString
{
int      size;       // 32-bit integer, contains size of the buffer, allocated for the string.
LPWSTR   buffer;     // 32-bit address of the buffer, containing the string.
int      reserved;   // 32-bit integer, reserved.
};
#pragma pack(pop,1)

Так,
Потрясенный этим солнечным воскресным днем, когда платформа претерпела LiveUpdate и внезапно все интерфейсы вызова DLL, использующие строку, перестали работать, потребовался долгий путь, чтобы покрыть расходы на такой «быстрый» технический сюрприз.

Вы можете повторно использовать найденное решение:

использовать массив байтов — uchar[] и соответствующим образом конвертировать байты возвращаемого контента на стороне MQL4 в string по сервисным функциям StringToCharArray() соответственно CharArrayToString()

DLL-.mqh-Заголовочный файл может также добавить эти уловки и сделать эти преобразования «скрытыми» из MQL4-кода:

#import <aDLL-file>                                       // "RAW"-DLL-call-interfaces
...
// Messages:
int      DLL_message_init(       int &msg[] );
int      DLL_message_init_size ( int &msg[], int    size );
int      DLL_message_init_data ( int &msg[], uchar &data[], int size );
...
#import

// ------------------------------------------------------ // "SOFT"-wrappers
...
int                MQL4_message_init_data ( int &msg[], string data, int size ) {  uchar dataChar[]; StringToCharArray( data, dataChar );
return (         DLL_message_init_data (      msg,          dataChar, size ) );
}

Всегда будьте осторожны с соответствующими освобождениями, чтобы не вызвать утечек памяти.

Всегда будьте довольно вежливы, когда новый LiveUpdate меняет базу кода и вводит новый компилятор + новую документацию. Перечитайте всю документацию, так как многие жизненно важные данные попадают в файл справки только после следующего обновления, а многие детали скрыты или косвенно отражены в главах, которые не обещают такую ​​информацию на первый взгляд, поэтому становятся готовый как Д’Артаньян или пионер в красном шарфе — вы никогда не знаете, откуда придет следующий хит 🙂

0

Другие решения

Других решений пока нет …

По вопросам рекламы [email protected]