后期绑定C ++ DLL到C# - 函数总是返回true

时间:2011-11-20 16:01:55

标签: c# c dllexport late-binding

我的h文件中有一个DLL:

extern "C" __declspec(dllexport) bool Connect();

并在c文件中:

extern "C" __declspec(dllexport) bool Connect()
{
     return false;  
}

在c#中我有以下代码:

[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
private delegate bool ConnectDelegate();

private ConnectDelegate DLLConnect;

public bool Connect()
{
    bool l_bResult = DLLConnect();
    return l_bResult;
}

public bool LoadPlugin(string a_sFilename)
{
   string l_sDLLPath = AppDomain.CurrentDomain.BaseDirectory;

   m_pDLLHandle = LoadLibrary(a_sFilename);
   DLLConnect = (ConnectDelegate)GetDelegate("Connect", typeof(ConnectDelegate));
   return false;
}

private Delegate GetDelegate(string a_sProcName, Type a_oDelegateType) 
{
    IntPtr l_ProcAddress = GetProcAddress(m_pDLLHandle, a_sProcName);
    if (l_ProcAddress == IntPtr.Zero)
       throw new EntryPointNotFoundException("Function: " + a_sProcName);

    return Marshal.GetDelegateForFunctionPointer(l_ProcAddress, a_oDelegateType);
}

出于某种奇怪的原因,无论C ++中的返回值是什么,connect函数总是返回true。 我已经尝试在C#中将调用约定更改为StdCall,但问题仍然存在。

有什么想法吗?

1 个答案:

答案 0 :(得分:4)

问题可能出在“bool”中。 在MSVC中,sizeof(bool)为1而sizeof(BOOL)为4! BOOL是Windows API用于表示布尔值的类型,是32位整数。 所以C#会消耗一个32位的值,但是你有一个1字节的值,所以你得到了“垃圾”。

有两种解决方案:

1)你改变你的C代码以返回BOOL或int。

2)您更改了将[return:MarshalAs(UnmanagedType.I1)]属性添加到dll导入功能的C#代码。