How to return a string from a C ++ DLL to the MetaTrader 4 code implementation ecosystem?

I have the following function

__declspec(dllexport) wchar_t* __stdcall __getJson(wchar_t * listN){
setlocale(LC_ALL, "");
//function logic
wstring ant = utf8_to_wstring(result);
const WCHAR* constRes = ant.c_str();
WCHAR* tempObj=new WCHAR[ant.length()];
wcscpy(tempObj, constRes);
thread Thread([tempObj]{
    Sleep(1000);
    delete[] tempObj;
});
Thread.detach();
return tempObj;
}

      

This DLL returns to MetaTrader4. wchar_t*

I tried many ways to return the correct value and avoid memory leaks, for example, setting the return type by const wchar_t*

creating my own class with a destructor from delete[]

in. But all attempts were unsuccessful: I got '??ello'

instead 'hello'

. Only one or two characters were wrong. With creation, thread

it works correctly. But, I want to know if there can be a better solution?

+3


source to share


3 answers


Be that as it may, I put my mind on BOOL APIENTRY DllMain

. So it solves my problem without creating threads.



vector<wchar_t*> tempObjVector;

BOOL APIENTRY DllMain(HMODULE hModule,DWORD  ul_reason_for_call,LPVOID lpReserved)
{
   switch (ul_reason_for_call)
   {
   case DLL_PROCESS_ATTACH:
   case DLL_THREAD_ATTACH:
   case DLL_THREAD_DETACH:
   case DLL_PROCESS_DETACH: 
       while (tempObjVector.size() != 0)
       {
           delete[] tempObjVector.back();
           tempObjVector.pop_back();
       }
       break;
   }
   return TRUE;
}

__declspec(dllexport) wchar_t* __stdcall __getJson(wchar_t * listN){
    ....
    ....
    wchar_t* tempObj=new wchar_t[ant.length()+1];
    tempObj[ant.length()] = 0;
    wcscpy(tempObj, constRes);
    tempObjVector.push_back(tempObj);
    return tempObj;
}

      

0


source


To create a string in your DLL and pass it to the caller, you must dynamically allocate some memory in the DLL to store string characters and pass a pointer to that memory to the caller.

In addition, the caller must be able to free this memory when the string is no longer needed.

To make it workable, you must use the same memory manager / allocator to allocate and free the row.

One option is to use a common system-wide distributor such as the COM distributor. That way, you can allocate memory in the DLL using CoTaskMemAlloc

, and the caller can free it using the appropriate CoTaskMemFree

.



Another option is to return the DLL BSTR

allocated string SysAllocString

. And the caller will release that line to the caller SysFreeString

.

Or, you can provide a custom function to free the string memory in your DLL. For example, you can allocate a string of memory in your DLL using new[]

, and you can provide a function MyDllFreeString

that calls delete[]

.

Note that when you allocate memory for a C-style string, you should consider an extra slot for a NUL string terminator (so you must allocate stringLength + 1

wchar_t

s).

+1


source


# ol 'ASM hackers always used to start
#assume nothing ; mql4_string != string

Bingo, headgear is obvious. The receiving side does not assume, since a new- was introduced MQL4.56789

, it is a representation of a block of bytes as , but (!) . string

struct

(cit. :) The internal representation of a string type is a 12 byte structure:

#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)

      

(cit. :) (MQL4-side doc :) The type is used to store text strings. A text string is a sequence of Unicode characters with a trailing zero at the end.
String Type



string

+1


source







All Articles