我是一名经验丰富的软件工程师,但对C#来说有点新鲜。我有一个DLL,它由带有C接口的C ++对象组成,如图所示。我使用这个C接口,因为我不确定是否有办法从我的C#应用程序访问DLL中的C ++入口点。
__declspec(dllexport) void *Constructor();
__declspec(dllexport) void Destructor(void *pObj);
__declspec(dllexport) int Method(void *pObj, char *pSrcDst, int len);
这是上述界面的C代码。
extern "C" void *Constructor()
{
return (void *)new Object;
}
extern "C" void Destructor(void *pObj)
{
delete (Object *)pObj;
}
extern "C" int Method(void *pObj, char *pSrcDst, int len)
{
if (!pObj) return 0;
return ((Object *)pObj)->Method(pSrcDst, len);
}
到目前为止一切顺利。现在,我需要能够从C#应用程序访问此接口。据我所知,我已经实现了以下C#接口。
unsafe public class Wrapper
{
[SuppressUnmanagedCodeSecurityAttribute()]
[DllImport("MyDLL.dll")]
public static extern
IntPtr Constructor();
[SuppressUnmanagedCodeSecurityAttribute()]
[DllImport("MyDLL.dll")]
public static extern
void Destructor(IntPtr pObj);
[SuppressUnmanagedCodeSecurityAttribute()]
[DllImport("MyDLL.dll")]
public static extern
int Method(IntPtr pObj, [In,Out] byte[] pSrcDst, int len);
这是使用上述界面的C#代码。
private IntPtr pObject;
public object()
{
pObject = Wrapper.Constructor();
}
~object()
{
Wrapper.Destructor(pObject);
}
public override byte[] method()
{
byte[] bytes = new byte[100];
int converted = Wrapper.Method(pObject, bytes, bytes.length);
return bytes;
}
代码在调用Wrapper.Method以及Wrapper.Destructor时都会断言。我假设我没有正确处理指向对象的指针。有什么建议吗?
答案 0 :(得分:3)
最可能的问题是您的代码没有使用正确的calling convention。在C ++中,默认值为__cdecl
,但对于DllImport
,默认值为__stdcall
。
要解决此问题,specify the calling convention explicitly:
[DllImport("MyDLL.dll", CallingConvention = CallingConvention.Cdecl)]
答案 1 :(得分:1)
我的印象是,执行此类操作的最佳方法是使用托管c ++ / CLI包装器。
Creating simple c++.net wrapper. Step-by-step
和
http://devmaster.net/forums/topic/7357-how-to-build-a-net-wrapper-for-a-c-library/
看起来很有前途。