如何将未知大小的字符串从 DLL 返回到 Visual Basic
我有一个可视化的基本脚本,它调用一个 DLL,该 DLL 执行网络请求并将一个请求的结果作为字符串返回.在调用 DLL 之前,结果的长度是未知的.DLL 是我自己用 C/C++ 编写的.
I have a visual basic script that calls to a DLL which does network requests and returns the result of one request as a string. The length of the result is unknown before calling the DLL. The DLL is written in C/C++ by myself.
据我所知,从 DLL 返回字符串的最常用方法是将预分配的字符串对象的引用作为参数传递给 DLL.DLL 函数然后只是用返回的字符串填充这个内存.问题是分配的缓冲区必须足够大,以确保结果适合它.
As far as I see, the most often used way to return strings from a DLL is to pass a reference of a preallocated string object as arguement to the DLL. The DLL function then just fills this memory with the returning string. The problem is that the allocated buffer has to be large enough, to make sure the result fits into it.
是否可以直接从 DLL 返回结果字符串?或者有没有其他方法可以根据结果的长度动态分配一个字符串对象并将其返回给VB调用者?
Is it possible to directly return the resulting string from the DLL? Or is there any other way to dynamically allocate a string object depending on the length of the result and return it to a VB caller?
我尝试了不同的方法,例如这样(丑陋的,只是示例):
I tried different approaches, for example like this (ugly, just examples):
__declspec(dllexport) const char* sendCommand(const char* cmd, const char* ipAddress)
{
// do request stuff...
long lengthOfResult = ...
const char* result = new char[lengthOfResult];
return result;
}
或者喜欢..
__declspec(dllexport) BSTR sendCommand(const char* cmd, const char* ipAddress)
{
_bstr_t result("Test string.");
BSTR bstrResult = result.copy();
return bstrResult;
}
视觉基础方面:
Declare Function sendCommand Lib "magicdll.dll" (cmd as String, ip as String) As String
result = sendCommand("any command", "192.168.1.1")
都没有成功 - VB 中的结果字符串充满了垃圾.
Both without success - the resulting string in VB is filled with garbage.
推荐答案
大多数 DLL 不返回一个字符串.他们接受一个字符串作为参数并将一个字符数组复制到该缓冲区中.尝试这样的事情:
Most DLLs don't return a string. They accept a string as a param and copy a char array into that buffer. Try something like this:
_declspec(dllexport) int sendCommand(const char* cmd,
const char* ipAddress,
char* pszBuffer,
int nBufferSize)
然后将您的字符串复制到该缓冲区并返回字符数:
And then copy your string into that buffer and return the number of chars:
int nSize = nBufferSize;
if (lstrlen(szMyResult) < nBufferSize)
nSize = lstrlen(szMyResult);
lstrcpyn(pszBuffer, szMyResult, nSize);
return nSize;
从VB调用时,分配一个字符串并指定其大小:
When calling from VB, allocate a string and specify its size:
Dim s As String, intChars As Long
s = Space$(128)
intChars = sendCommand("...", "...", s, Len(s))
s = Left$(s, intChars)
如果您必须返回一个字符串作为函数调用的结果,您可以尝试创建一个 BSTR(一个 VB 样式的字符串)并返回它.您需要将字符串转换为 Unicode,然后使用 SysAllocString()
创建 BSTR.例如:
If you must return a string as the result of your function call, you can try creating a BSTR (a VB-style string) and returning that. You'll need to convert your string to Unicode and then use SysAllocString()
to create the BSTR. For example:
BSTR ReturnVBString()
{
return SysAllocString(L"This string is from a C DLL.");
}
相关文章