从 dll 返回多个字符串
Return multiple strings from dll
我们正在讨论从一个DLL函数返回多个字符串的好方法。目前我们有 8 个字符串,但还会有更多。为简单起见,我现在考虑所有字符串的长度相等。
extern "C" int DLLNAME_ _stdcall GetResult(TestResults* testResults);
哪里
struct TestResults
{
int stringLengths;
char* string1;
char* string2;
char* string3;
char* string4;
...
};
或第二种选择:其中
struct TestResults
{
int stringLengths;
char string1[64];
char string2[64];
char string3[64];
char string4[64];
...
};
第三种选择: extern "C" int DLLNAME_ _stdcall GetResult(int stringLengths, char* string1, char* string2, char* string3, ...);
dll 将通过串行线路进行通信,并检索将填充到字符串中的信息。需要分配内存的位置可以讨论,并且可以成为答案的一部分。
背景是,我们有一个首选第二种方法的 VB6 应用程序团队和一个首选第一种方法的 C++/C# 团队。最后一种方法看起来适合两个团队,但对我来说看起来有点奇怪,有这么多参数。
也许还有更多选择。Windows下的常见做法是什么?Windows API 中的任何示例或参数可以选择一个而不是另一个?
编辑:字符串的含义与名字,姓氏,电子邮件一样。我们目前有八个,但将来我们可能会添加几个例如地址。数组不是正确的选择,但这在原始上下文中并不清楚。
最好的方法可能是使用存储BSTR
字符串的安全数组。
VB 和 C# 都非常了解安全数组:在 C# 中,BSTR
字符串的安全数组会自动转换为string[]
数组。
在C++端,可以使用ATL::CComSafeArray
帮助程序类来简化安全数组编程。
您将在这篇 MSDN 杂志文章中找到有趣的材料(特别是,请查看生成字符串的安全数组段落)。
从前面提到的文章中: 在C++端,你可以实现一个C 接口DLL,导出一个函数,如下所示:
extern "C" HRESULT MyDllGetStrings(/* [out] */ SAFEARRAY** ppsa)
{
try {
// Create a SAFEARRAY containing 'count' BSTR strings
CComSafeArray<BSTR> sa(count);
for (LONG i = 0; i < count; i++) {
// Use ATL::CComBSTR to safely wrap BSTR strings in C++
CComBSTR bstr = /* your string, may build from std::wstring or CString */ ;
// Move the the BSTR string into the safe array
HRESULT hr = sa.SetAt(i, bstr.Detach(), FALSE);
if (FAILED(hr)) {
// Error...
return hr;
}
}
// Return ("move") the safe array to the caller
// as an output parameter (SAFEARRAY **ppsa)
*ppsa = sa.Detach();
} catch (const CAtlException& e) {
// Convert ATL exceptions to HRESULTs
return e;
}
// All right
return S_OK;
}
在 C# 端,可以使用以下 PInvoke 声明:
[DllImport("MyDll.dll", PreserveSig = false)]
public static extern void MyDllGetStrings(
[Out, MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)]
out string[] result);
当您将函数声明为extern "C"
时,我想您不能将std::vector<std::string>
用作返回类型。
另一种可能性是:
struct String
{
int size; /* size of string */
const char* str; /* actual string */
}
struct TestResults
{
int size; /* number of strings */
String* arr; /* pointer to an array of String */
};
然后和以前一样:
extern "C" int DLLNAME_ _stdcall GetResult(TestResults* testResults);
有了它,您可以灵活地返回任意数量的字符串。循环浏览您的TestResults
也很容易。
编辑#1:如评论中所述:使用BSTR。因此,您的结构将如下所示:
struct TestResults
{
int size; /* number of strings */
BSTR* arr; /* pointer to an array of BSTR */
};
BSTR
将按以下方式分配:BSTR MyBstr = SysAllocString(L"I am a happy BSTR");
。此分配还设置包含字符串长度的成员。您必须通过以下方式释放分配的内存:SysFreeString(MyBstr);
。您还需要分配整个数组BSTR*
。
- C 字符串返回字符串的整数/双精度/长整型值
- std::hash<std::string> 可以为不同的字符串返回相同的值吗?
- Java 调用 dll 字符串返回类型方法
- 返回具有C++字符串返回值的函数的本地 C 字符串
- 如何将两个 jlong 数据类型转换为 jstring,然后将两个字符串连接在一起以便从 JNI 将字符串返回给 jav
- 尝试以随机字符(长读取)打印字符串返回结果
- 从字符串返回 i(索引)字
- 函数读取最大和min int值,并用文本字符串返回
- 如何将 YAML 节点中的序列作为字符串返回?
- 将注册表项读取为字符串返回数值
- 为什么我在尝试打印字符串返回时收到编译器错误?
- 使用 char*array 存储条形图的条形图,以便我可以动态制作它并作为字符串返回
- 字符串返回功能不起作用 - 'identifier is underfined'
- 将C 本地字符串返回到另一个功能
- 在MATLAB中仅接受INT32PTR时,将错误编号作为字符串返回
- 字符串流到字符串返回
- 字符串返回错误的长度
- 从共享指针矢量字符串返回值
- C++随机字符串返回意外结果
- 临时标准::字符串返回垃圾