字符串参数未正确封送到 DLL C++

本文关键字:DLL C++ 参数 字符串 | 更新日期: 2023-09-27 17:56:13

我得到了一个由C#调用的DLL。DLL 包含两个方法,如下所示

extern "C" {
   __declspec(dllexport) BSTR GroupInit(LPCTSTR bstrIniFile, bool bDiagErr, bool bProcErr);
} 
BSTR GroupInit(LPCTSTR bstrIniFile, bool bDiagErr, bool bProcErr) {
   CString strResult = "";
   char* sz;
   ::SetVars(bDiagErr, bProcErr);
   if (sz = ::GroupInit((char*)bstrIniFile, 1))
      strResult = sz;
   return strResult.AllocSysString();
}

我尝试通过首先定义类从 C# 调用这些 DLL:

[DllImport("GrouperServer.dll", CallingConvention = CallingConvention.Cdecl)]
[return: MarshalAs(UnmanagedType.BStr)]
public static extern string GroupInit(
    string strCmdFile, 
    bool bAllowBadDiagCodes, 
    bool bAllowBadProcCodes
);

和做

this.strCommandFilePath = "C:''MyDir''MyCommandFile.txt";
string s = Grouper.GrouperServer.GroupInit(this.strCommandFilePath, true, true);

但是 DLL 返回错误:"找不到命令文件:"C"(仅路径的第一个字符,我已经在C++ DLL 中检查过)。由于某种原因,字符串this.strCommandFilePath未正确传递到 C++ 方法中。

上面的电话有什么问题?


编辑以解决评论。

if (sz = ::GroupInit((char*)bstrIniFile, 1)) 语句中调用的方法在 .c 文件中定义,并具有签名

char *GroupInit(char *szCmd, int iType)
{
   ...
}

字符串参数未正确封送到 DLL C++

在这里使用TCHAR和相关类型是错误的。TCHAR的用例是针对需要为不支持Unicode的Windows 9x和不支持Unicode的Windows NT编译的代码。那些日子早已一去不复返了,TCHAR掩盖了这个问题。更重要的是,底层代码使用char*所以假装你的包装器代码可以做任何其他事情是没有意义的。所以切换到 char .

最重要的是,你正在抛弃康斯特。我猜是因为您调用的函数接受它不会修改的参数的可修改缓冲区。最好的解决方案是修复错误接受char*的原始库代码,并使其接受const char*。如果你做不到这一点,那么你就需要抛弃常量。但是用const_cast<> C++的方式做到这一点.

所以,我会有这样的C++代码:

BSTR GroupInit(const char* szIniFile, bool bDiagErr, bool bProcErr) {
   CString strResult = "";
   char* sz;
   ::SetVars(bDiagErr, bProcErr);
   if (sz = ::GroupInit(const_cast<char*>(szIniFile), 1))
      strResult = sz;
   return strResult.AllocSysString();
}

C# 代码应该是:

[DllImport("GrouperServer.dll", CallingConvention = CallingConvention.Cdecl,
    CharSet = CharSet.Ansi)]
[return: MarshalAs(UnmanagedType.BStr)]
public static extern string GroupInit(
    string strCmdFile, 
    bool bAllowBadDiagCodes, 
    bool bAllowBadProcCodes
);

现在,人们想知道sz会发生什么.谁应该释放它?它甚至需要解除分配吗?只有你能回答这些问题。