需要一些帮助来弄清楚为什么我无法通过调用下面的这个 dll 函数获得预期的结果。从可执行文件中调用外部 dll 函数并返回乱码结果。如果我收到乱码字符串,就会发回一些东西,对吗?
// calling code
const wchar_t *symptr = expFunc8(id);
printf("%s\n", symptr); // prints this garbled string 0·o_²⌂
// dll function
EXPFUNC const wchar_t* __stdcall expFunc8(const unsigned int id) {
wchar_t symbuf[BUFFER_128];
memset(symbuf, 0x00, BUFFER_128);
swprintf_s(symbuf, BUFFER_128 - 1, L"%s", symM[id]->name); // name is char[]
const wchar_t *symptr = &symbuf[0];
printf("%s\n", symptr); // prints expected result so ptr is fine
return symptr;
}
如果我传入一个缓冲区指针,它可以工作,但是是否可以返回一个指针,或者这是唯一的方法?
EXPFUNC void __stdcall expFunc8(const unsigned int id, wchar_t *buf) {
swprintf_s(buf, BUFFER_128 - 1, L"%s", symM[id]->name);
}
蒂亚
从 C++ 函数中获取字符串有两种方法:
方法 1. 调用代码创建一个缓冲区并将其传递给函数。函数将结果写入缓冲区。该函数可以为空。
方法 2. 函数使用
new wchar_t[BUFFER_SIZE]
分配缓冲区并返回指向缓冲区的指针。调用代码负责使用 delete
释放内存。
除了正确处理内存之外,您还需要确保使用单字节
char
类型与“宽字符”wchar_t
字符串保持一致。您可能需要将一种类型转换为另一种类型。请注意,对于宽字符串文字,请使用 wprintf
和 L"..."
。
此外,当您使用
memset
等内存函数和宽字符字符串时,请记住区分以字节为单位的内存大小和以宽字符为单位的字符串长度。注意使用 length*sizeof(wchar_t)
初始化缓冲区时传递 memset
。
调用代码
wchar_t clientBuffer[BUFFER_128];
expFunc8(id, clientBuffer, BUFFER_128);
wprintf(L"%s\n", clientBuffer); // should print correct string
DLL函数
EXPFUNC void __stdcall expFunc8(const unsigned int id,
wchar_t* symbuf, int bufferSize)
{
memset(symbuf, 0x00, bufferSize*sizeof(wchar_t));
// Since name is char[] convert it to wide char
// check if the name is longer than the buffer size
// and handle the error
int length = strlen(symM[id]->name);
if (length >= bufferSize)
length = bufferSize - 1;
mbstowcs(symbuf, symM[id]->name, length);
wprintf(L"%s\n", symbuf); // prints expected result
}
调用代码
wchar_t* functionAllocatedBuffer = expFunc8(id);
wprintf(L"%s\n", functionAllocatedBuffer); // should print correct string
// calling code has to free the memory allocated by the function
delete functionAllocatedBuffer;
DLL函数
EXPFUNC wchar_t* __stdcall expFunc8(const unsigned int id)
{
// Since name is char[] convert it to wide char
// check if the name is longer than the buffer size
// and handle the error
int length = strlen(symM[id]->name);
if (length >= bufferSize)
length = bufferSize - 1;
wchar_t* symbuf = new wchar_t*[length];
memset(symbuf, 0x00, length*sizeof(wchar_t));
mbstowcs(symbuf, symM[id]->name, length);
wprintf(L"%s\n", symbuf); // prints expected result
}