未处理的异常:系统.AccessViolationException:试图读取或写入受保护的内容



问题:运行.exe 时出错

类型为"System"的未处理异常。AccessViolationException发生在AddingWrapper.dll 中

附加信息:试图读取或写入受保护的内存。这通常表示其他内存已损坏。

在控制台中,它写道:

未处理的异常:系统。AccessViolationException:尝试读或写保护存储器。这通常表明内存已损坏。在gcroot(添加^)。。P$AAVAdd@@(gcroot(Add^))AddingWrapper。添加(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

终端类

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 <msclrauto_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吗?还是其他问题?所有其他线程的答案似乎都不一样(即,其中一个线程暗示用户帐户并不拥有计算机的所有权限)。如果我错过了这些线程,请将其链接到我,这个错误正在杀死我

我还应该补充一下,这个错误是在运行时而不是编译时。

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中只有指针,不指向任何内容;这会导致访问冲突。将它们更改为自动对象("在堆栈上")将解决此问题。如果需要动态对象,则可以new(之后再delete);而是倾向于诸如CCD_ 8和CCD_。

几件事:

  • 您还没有显示您的VB代码。由于您编写的是非托管类,而不是托管类,因此导入可能不正确,或者您传递了一个错误的指针
  • 为什么要将int*传递到包装器,却在那里取消引用它?为什么不通过int
  • 您使用的是C++/CLI,为什么不编写托管类?您不需要auto_gcroot,也不需要处理DLL导入/导出:VB.Net可以像看到任何类一样看到您的类。Net类,并像引用任何类一样容易地引用它。Net库

编辑

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

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

您不需要为基本数据类型传递指针,因此如果您愿意,可以去掉整个指针。事实上,它在VB中是一个double,但在C++中是int,这很好,C++/CLI知道VB代码使用double,并将进行适当的转换。

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

最新更新