在C#中导入C++ DLL,函数参数

use*_*807 2 c# c++ string pinvoke

我正在尝试在C#中导入我的C++ Dll.它似乎适用于没有参数的函数,但我的函数有一些问题.

我的C++功能:

__declspec(dllexport) bool SetValue(const std::string& strV, bool bUpload)
{ 
    return ::MyClass::SetValue(strV.c_str(), bUpload);              
}
Run Code Online (Sandbox Code Playgroud)

它包含在"extern"C"{"中

该函数调用另一个函数:

bool SetValue(const char* szValue, bool bUpload)
{
}
Run Code Online (Sandbox Code Playgroud)

我的C#功能:

[DllImport("MyDll.dll", EntryPoint = "SetValue", CharSet = CharSet.Auto, SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
        public static extern void SetValue([MarshalAs(UnmanagedType.LPStr)]string strVal, bool bUpload);
Run Code Online (Sandbox Code Playgroud)

当我使用调试模式并输入SetValue(const char*sZvalue,bool bUpload)函数时,sZvalue为"0x4552494F",但是当我尝试扩展Visual Studio的视图以查看其值为"undefined value"的值时.

也许有人知道我的代码有什么问题?

谢谢 !

Dav*_*nan 5

你不能希望通过std::string使用pinvoke.A std::string是一个只能在C++代码中使用的C++类.

你的选择:

  1. 编写C++/CLI包装器.
  2. 使用互操作友好类型,如const char*BSTR.

您似乎已经拥有了接受的函数版本const char*.你可以轻松地调用它.

[DllImport("MyDll.dll", CallingConvention = CallingConvention.Cdecl)]
public static extern void SetValue(
    string strVal, 
    [MarshalAs(UnmanagedType.I1)]
    bool bUpload
);
Run Code Online (Sandbox Code Playgroud)

显然你需要导出所SetValue接受的版本const char*.

请注意,SetLastError除非您的API实际调用,否则不应使用此处SetLastError.如果它这样做会是不寻常的.它往往是Win32 API函数.

正如@Will指出的那样,您应该使用MarshalAs告诉编组器该bool参数将被编组为单字节C++ bool而不是默认的4字节Windows BOOL.