我正在C#中实现C++ Dll。
我的包装器.h文件:
'
class __declspec(dllexport) TestClass
{
public:
int value;
TestClass(int value):value(value)
{
}
~TestClass()
{
}
}
'
我的包装器.cpp文件
#include "stdafx.h"
#include "WrapperApplication.h"
我的 C# 代码
public unsafe class Message:IDisposable
{
private TestStruct* _testStruct;
private IntPtr* _oldVTable;
[DllImport(@"WrapperApplication.dll", EntryPoint = "??0TestClass@WrapperApplication@@QAE@H@Z", CallingConvention = CallingConvention.ThisCall)]
extern static IntPtr Test(TestStruct* testStruct, int value);
public Message(int value)
{
_testStruct=(TestStruct*)Memory.Alloc(sizeof(TestStruct));
Test(_testStruct, value);
}
#region IDisposable Members
public void Dispose()
{
//throw new NotImplementedException();
}
#endregion
}
我的测试结构.cs文件:
[StructLayout(LayoutKind.Sequential, Pack = 4)]
public unsafe struct TestStruct
{
public IntPtr* vtable;
public int value;
}
我必须在.Net应用程序中的Vtable的帮助下调用CPP dll。我已经创建了TestStruct.cs文件作为My Cpp类的副本。并尝试在 C# 构造函数中调用 CPP 构造函数。但是在 Test(_testStruct, value); 行抛出 System.AccessViolation 异常作为尝试读取或写入内存。这通常表示其他内存已损坏。_teststruct的值,测试 ctor 中的值来了,但它仍然抛出异常。我已经尝试了很多方法,但未能获得解决方案。请让我知道我在实施中哪里有问题。所以任何帮助将不胜感激。
我认为最简单的方法是不要直接从 C# 调用C++接口 DLL。有了这个前提,两种方式出现在你面前:
- 为 DLL 提供一个平面 C 接口或组件对象模型 (COM) 接口。这将使它可以从大多数平台和语言调用。
- 保持 DLL 原样,但从 C++/CLI 代码而不是 C# 代码调用它。毕竟,这就是 C++/CLI 存在的原因:在 .Net Framework 应用程序和非托管库之间制作这种粘合代码。
由于您首先调用的是非托管代码,因此请确保Dispose()
非托管资源。有一种方法可以捕获非托管代码引发的异常(如果失败的模块是非托管组件)。使用 HandleProcessCorruptedStateExceptions
属性修饰 Message()
方法,该属性将捕获非托管代码引发的任何异常。
[HandleProcessCorruptedStateExceptions]
public Message(int value)
{
try
{
_testStruct=(TestStruct*)Memory.Alloc(sizeof(TestStruct));
Test(_testStruct, value);
}
Catch(AccessViolationException ex)
{
//Read the exception here
}
}