在 .Net 应用程序中调用 C++ DLL 时出现系统访问冲突异常

本文关键字:系统 访问冲突 异常 DLL 应用程序 Net 调用 C++ | 更新日期: 2023-09-27 18:33:49

我正在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 中的值来了,但它仍然抛出异常。我已经尝试了很多方法,但未能获得解决方案。请让我知道我在实施中哪里有问题。所以任何帮助将不胜感激。

在 .Net 应用程序中调用 C++ DLL 时出现系统访问冲突异常

我认为最简单的方法是不要直接从 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
      }
   }