c# - 字符串参数未正确编码到 C++ DLL

标签 c# c++ parameters pinvoke

我已经获得了一个由 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)
{
   ...
}

最佳答案

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

最重要的是,你正在抛弃 const。我猜是因为您调用的函数接受一个可修改的缓冲区,用于它不修改的参数。最好的解决方案是修复错误接受 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 会发生什么.谁应该解除分配?它甚至需要被释放吗?只有您才能回答这些问题。

关于c# - 字符串参数未正确编码到 C++ DLL,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22809189/

相关文章:

创建 pthread 时出现 C++ 段错误

C++如何使dll从主线程修改变量?

java - ClassLoader 加载带参数的小程序

c# - 当用户键入或更改电子邮件正文时是否有任何撰写邮件的事件

c# - 通过子网掩码计算IP范围

c# - 使用 MVVM 模式实现异步 "loadData"方法的最佳方式

c# - 如何在C#中使用SignalR向特定用户发送数据?

带有指针的 C++ 类模板特化

python - 从一个 python 脚本到另一个传递简单参数的简单调用

parameters - AngularJS:用于路由的 url 参数