未处理的异常:System.AccessViolationException:试图读取或写入保护

Unhandled Exception: System.AccessViolationException : attempted to read or write protected

问题: 运行 运行我的 .exe

时出现错误

An unhandled exception of type 'System.AccessViolationException' occurred in AddingWrapper.dll

Additional information: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.

它在控制台中这样写:

Unhandled Exception: System.AccessViolationException : attempted to read or write protected memory. This is often an indication that other memory is corrupt. at gcroot (Add ^).. P$AAVAdd@@(gcroot(Add^)) at AddingWrapper.Adding(AddingWrapper, Int32* x, Int32* y)

代码片段:

VB代码:

Public Class Add
  Public Function Adding(ByVal x As Double, ByVal y As Double) As Integer
      Return x + y
   End Function

结束Class

AddingWrapper.h:

#pragma once
#include "stdafx.h"

class AddingWrapperPrivate;


class __declspec(dllexport) AddingWrapper {

private: AddingWrapperPrivate* _private;
public: AddingWrapper();
        int Adding(int* x, int* y);
       ~AddingWrapper();

};

AddingWrapper.cpp

#include "stdafx.h"

#include "AddingWrapper.h"

#using "Class1.dll"
#include <msclr\auto_gcroot.h>
using namespace System::Runtime::InteropServices;

class AddingWrapperPrivate {
  public: msclr::auto_gcroot<Add^> add;
};

AddingWrapper::AddingWrapper()
{
    _private = new AddingWrapperPrivate();
    _private->add = gcnew Add();
};
int AddingWrapper::  Adding(int* x, int* y) {
    return _private->add->Adding(*x, *y);
};
AddingWrapper::~AddingWrapper()
{
    delete _private;
};

调用代码:

 #include "stdafx.h"
 #include "AddingWrapper.h"
 #include <iostream>
    int main()
{
  int *a = 0;
   int *b = 0;
   AddingWrapper *add;
   int results =  add->Adding(a,b);
   std::cout << "here is the result";
   std::cout << results;
   return 0;
 }

难道是因为我在AddingWrapper.cpp中的Class1.dll使用了VB.net?还是其他问题的问题?所有其他线程的答案似乎都不同(即一个暗示用户帐户没有计算机的所有权限)。如果我错过了那些线程,请 link 告诉我,这个错误让我丧命

我还应该添加这个错误是在 运行 时间而不是编译时间。

几件事:

  • 您还没有显示您的 VB 代码。由于您编写的是非托管的 class,而不是托管的,似乎导入不正确,或者您传递的指针不正确。
  • 为什么要将 int* 传递给包装器,只是为了在那里取消引用它?为什么不通过 int?
  • 您在使用 C++/CLI,为什么不编写托管 class?您不需要 auto_gcroot,也不需要处理 DLL imports/exports:VB.Net 可以看到您的 class,就像它可以看到任何.Net class,并像引用任何 .Net 库一样轻松地引用它。

编辑

好的,您试图从 C++ 调用一些 VB.Net 代码并不明显。我以为你想往另一个方向走。

问题几乎可以肯定是您向 AddingWrapper::Adding 传递了错误的指针。

您不需要为基本数据类型传递指针,因此您可以根据需要摆脱整个事情。事实上它在 VB 中是一个双精度数但在 C++ 中是一个 int 很好,C++/CLI 知道 VB 代码采用双精度数并将适当地转换。

另外,请注意您不是在托管代码和非托管代码之间传递指针。您正在将一个指针从一个非托管 class 传递到另一个非托管 class(无论调用 AddWrapper 还是传递给 AddWrapper),但是跨越 managed/unmanaged 边界,您传递的是一个普通的旧 int.

main 函数中,您正在使用 "null" 对象指针并传入 NULL 指针 - 这将导致您看到的错误。

int main()
{
   int a = 1;
   // ^^^ remove the pointer (and give it a "interesting" value)
   int b = 2;
   // ^^^ remove the pointer
   AddingWrapper add; // remove the pointer (or allocate with new)
   //          ^^^ remove the pointer
   int results = add.Adding(&a, &b); // pass in the address of the integers
   //              ^^^ syntax change

   std::cout << "here is the result";
   std::cout << results;
   return 0;
 }

变量abadd其中只有指针,没有指向任何东西;这会导致访问冲突。将它们更改为自动对象 ("on the stack") 将解决此问题。如果需要动态对象,您可以 new 它们(然后 delete 它们);但喜欢 std::shared_ptrstd::unique_ptr 等库实用程序来帮助管理对象的生命周期。