0

我在 C# 中实现 C++ Dll。

我的 Wrapper.h 文件:

`

    class __declspec(dllexport) TestClass
     {   
      public:
              int value;
              TestClass(int value):value(value)
              {
              }
             ~TestClass()
              {
              }
     }

`

我的 Wrapper.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
}

我的 TestStruct.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 的值,Test ctor 中的值来了,但它仍然抛出异常。我尝试了很多方法,但未能得到解决方案。请让我知道我在实施中哪里错了。因此,任何帮助都会受到赞赏。

4

2 回答 2

1

我认为最简单的方法是不要直接从 C# 调用 C++ 接口 DLL。有了这个前提,两种方式出现在你面前:

  • 为您的 DLL 提供一个平面 C 接口,或一个组件对象模型 (COM) 接口。这将使它可以从大多数平台和语言调用。
  • 保持 DLL 原样,但从 C++/CLI 代码而不是 C# 代码调用它。毕竟,这就是 C++/CLI 存在的原因:在 .Net Framework 应用程序和非托管库之间制作这种胶水代码。
于 2013-10-04T13:44:57.657 回答
0

由于您首先调用非托管代码,因此请确保您Dispose()使用非托管资源。有一种方法可以捕获非托管代码引发的异常(如果失败的模块是您的非托管组件)。使用属性装饰您的Message()方法,HandleProcessCorruptedStateExceptions该属性将捕获非托管代码引发的任何异常。

  [HandleProcessCorruptedStateExceptions]
   public Message(int value)
   {

    try
      {
         _testStruct=(TestStruct*)Memory.Alloc(sizeof(TestStruct));

         Test(_testStruct, value);
      }
    Catch(AccessViolationException ex)
      {
         //Read the exception here
      }
   }
于 2013-10-04T10:10:59.240 回答