从dll返回多个字符串

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或参数中的任何示例都可以选择其中一个?

编辑:字符串具有名字,姓氏,电子邮件的含义.我们目前有八个,但将来我们可能会添加一对例如地址.数组不是正确的选择,但原始上下文中并不清楚.

Mr.*_*C64 5

最好的方法可能是使用存储字符串的安全数组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)