我有以下功能
__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;
}
此DLL将 wchar_t*
返回给MetaTrader4。
我尝试了很多方法来返回正确的值并避免内存泄漏,例如set return type const wchar_t*
,使用带有delete[]
in的析构函数创建我自己的类。但是所有这些尝试都没有成功:我得到{ {1}}代替'??ello'
。只是前一个或两个符号不正确。通过创建'hello'
,它可以正常工作。但是,我想知道,可能有更好的解决方案吗?
答案 0 :(得分:1)
要在DLL中创建一个字符串并将其传递给调用者,您必须在DLL中动态分配一些内存来存储字符串的字符,并将指向该内存的指针传递给调用者。
此外,当不再需要字符串时,调用者必须能够释放该内存。
为了使其正常工作,您必须使用相同的内存管理器/分配器来分配和释放字符串的内存。
一种选择是使用像COM分配器这样的通用系统范围的分配器。通过这种方式,您可以使用CoTaskMemAlloc
在DLL中分配内存,并且调用者可以使用匹配的CoTaskMemFree
释放它。
另一种选择是返回一个BSTR
字符串,在DLL中分配SysAllocString
。调用者将释放该字符串,调用SysFreeString
。
或者,您可以提供自定义函数来释放DLL中的字符串内存。例如,您可以使用new[]
在DLL中分配字符串的内存,并且可以提供调用MyDllFreeString
的{{1}}函数。
请注意,为C风格的字符串分配内存时,必须考虑字符串的 NUL-terminator 的附加插槽(因此,您必须分配{{1} } delete[]
s)。
答案 1 :(得分:1)
#assume nothing ; mql4_string != string
MQL4.56789
被引入,它将字节块表示为 string
,但是 struct
(!)。
(cit。:)字符串类型的内部表示是一个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)
(cit。:) (MQL4-side doc :)
String Type
<登记/>string
类型用于存储文本字符串。文本字符串是Unicode格式的字符序列,最后为零。
答案 2 :(得分:0)
偶然的,我想到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;
}
。所以它在不创建线程的情况下解决了我的问题。
<xsl:copy>
<xsl:value-of select="format-number(., '#########0.##')"/>
</xsl:copy>
答案 3 :(得分:0)
另一种方式(稍微简单一点,但仅在某些情况下):
//C++
extern "C" __declspec(dllimport) const wchar_t *GetMessage();
const wchar_t *GetMessage()
{
static std::wstring last_message;
last_message = GetSomeMessage();
return last_message.c_str();
}
//MQL
#import "MyDll.dll"
string GetMessage();
#import
string message = GetMessage();