Jef*_*tat 3 c++ windows string dll
我们正在讨论什么是从一个dll函数返回多个字符串的好方法.目前我们有8个字符串,但会有更多.为简单起见,我现在认为所有字符串都有相同的长度.
extern "C" int DLLNAME_ _stdcall GetResult(TestResults* testResults);
Run Code Online (Sandbox Code Playgroud)
哪里
struct TestResults
{
int stringLengths;
char* string1;
char* string2;
char* string3;
char* string4;
...
};
Run Code Online (Sandbox Code Playgroud)
或第二种选择:在哪里
struct TestResults
{
int stringLengths;
char string1[64];
char string2[64];
char string3[64];
char string4[64];
...
};
Run Code Online (Sandbox Code Playgroud)
第三个选项: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;
}
Run Code Online (Sandbox Code Playgroud)
在C#端,您可以使用此PInvoke声明:
[DllImport("MyDll.dll", PreserveSig = false)]
public static extern void MyDllGetStrings(
[Out, MarshalAs(UnmanagedType.SafeArray, SafeArraySubType = VarEnum.VT_BSTR)]
out string[] result);
Run Code Online (Sandbox Code Playgroud)