未处理的异常: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;
}
变量a
、b
和add
其中只有指针,没有指向任何东西;这会导致访问冲突。将它们更改为自动对象 ("on the stack") 将解决此问题。如果需要动态对象,您可以 new
它们(然后 delete
它们);但喜欢 std::shared_ptr
和 std::unique_ptr
等库实用程序来帮助管理对象的生命周期。
问题: 运行 运行我的 .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;
}
变量a
、b
和add
其中只有指针,没有指向任何东西;这会导致访问冲突。将它们更改为自动对象 ("on the stack") 将解决此问题。如果需要动态对象,您可以 new
它们(然后 delete
它们);但喜欢 std::shared_ptr
和 std::unique_ptr
等库实用程序来帮助管理对象的生命周期。