Here is my code for a 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 );
}
On the MQL4-Caller side this Script is used:
#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 );
}
}
In this way it works, when a message
have been properly initialized with a StringInit()
function and enough memory was allocated.
What I need to do is, to allocate the message
variable not in MQL4 script, but within the DLL.
In a c++ function, should be something like this:
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 );
}
What can I do ?
string
to be string
( it is a struct
... since 2014 ) Internal representation of the string type is a structure of 12 bytes long:
#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)
So,
having headbanged into this one sunny Sunday afternoon, as the platform undergone a LiveUpdate and suddenly all DLL-call-interfaces using a string stopped work, it took a long way to absorb the costs of such "swift" engineering surprise.
You can re-use the found solution:
use an array of bytes - uchar[]
and convert appropriately bytes of returned content on MQL4 side into string
by service functions StringToCharArray()
resp. CharArrayToString()
The DLL- .mqh
-header file may also add these tricks and make these conversions "hidden" from MQL4-code:
#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 ) );
}
Always be pretty carefull with appropriate deallocations, not to cause memory leaks.
Always be pretty cutious when new LiveUpdate changes the code-base and introduces new compiler + new documentation. Re-read whole documentation, as many life-saving details come into the help-file only after some next update and many details are hidden or reflected indirectly in chapters, that do not promise such information on a first look -- so, become as ready as D'Artagnan or red-scarfed pioneer -- you never know, where the next hit comes from :)
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.