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

时间:2013-12-04 13:24:20

标签: 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);              
}

它包含在“extern”C“{”

该函数调用另一个函数:

bool SetValue(const char* szValue, bool bUpload)
{
}

我的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);

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

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

谢谢!

2 个答案:

答案 0 :(得分:5)

您不能希望使用std::string传递pinvokestd::string是一个只能在C ++代码中使用的C ++类。

您的选择:

  1. 编写C ++ / CLI包装器。
  2. 使用互操作友好类型,例如const char*BSTR
  3. 您似乎已经拥有接受const char*的函数版本。你可以很容易地调用它。

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

    显然,您需要导出已接受SetValue的{​​{1}}版本。

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

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

答案 1 :(得分:0)

我不确定但你应该使用StringBuilder来试试这个:

[DllImport("MyDll.dll", EntryPoint = "SetValue", CharSet = CharSet.Auto, SetLastError = true, CallingConvention = CallingConvention.Cdecl)]
    public static extern void SetValue(StringBuilder strVal, bool bUpload);