Pointers C++/CLI指针问题=有趣! 我一直把一组旧的C++代码转换成C++/CLI代码,我想我已经把自己编码成一个角落。 我的目标是采用一个非托管C++库和一组头文件,并将它们的功能暴露给C语言解决方案。通过互联网阅读,实现这一目标的标准方法是: < LI>创建两个C++类:一个托管,另一个非托管。 非托管类将在C++库中对对象进行扭曲以提供所需的功能。 托管类将在非托管类中包装所有公共方法。每个包装器方法将处理从字符串^到字符串等的必要转换
但是,我的场景并不复杂,所以我决定尝试在一个类中实现所有内容。我现在正在努力解决一个生成AccessViolationException的特殊问题 我的头文件如下所示:Pointers C++/CLI指针问题=有趣! 我一直把一组旧的C++代码转换成C++/CLI代码,我想我已经把自己编码成一个角落。 我的目标是采用一个非托管C++库和一组头文件,并将它们的功能暴露给C语言解决方案。通过互联网阅读,实现这一目标的标准方法是: < LI>创建两个C++类:一个托管,另一个非托管。 非托管类将在C++库中对对象进行扭曲以提供所需的功能。 托管类将在非托管类中包装所有公共方法。每个包装器方法将处理从字符串^到字符串等的必要转换,pointers,c++-cli,c#-2.0,Pointers,C++ Cli,C# 2.0,但是,我的场景并不复杂,所以我决定尝试在一个类中实现所有内容。我现在正在努力解决一个生成AccessViolationException的特殊问题 我的头文件如下所示: public ref class ManagedClass { public: ManagedClass(); void CreateUnmanagedObject(String^ param1); void UseUnmanagedObject(); UnmanagedObject *myUnmanagedO
public ref class ManagedClass
{
public:
ManagedClass();
void CreateUnmanagedObject(String^ param1);
void UseUnmanagedObject();
UnmanagedObject *myUnmanagedObject;
}
void ManagedClass::CreateUnmanagedObject(String^ param1)
{
/* Convert params, use them in some way. */
/* capture the output of this library call to the pointer defined in ManagedClass.*/
myUnmanagedObject= &(LibrayObject.LibraryMethod1());
}
void ManagedClass::UseUnManagedObject()
{
/* This function will pass the Unmanaged object into
* a library function which will do some work on it.
*/
LibraryObject.LibraryMethod2(*myUnmanagedObject);
/* Whoops! System.AccessViolationException is thrown! */
}
UnmanagedObject LibraryMethod1();
void LibraryMethod2(UnmanagedObject ¶m);
class Unmanagedclass {
public:
Unmanagedclass(const char* arg) {}
void mumble() {}
};
我的cpp文件如下所示:
public ref class ManagedClass
{
public:
ManagedClass();
void CreateUnmanagedObject(String^ param1);
void UseUnmanagedObject();
UnmanagedObject *myUnmanagedObject;
}
void ManagedClass::CreateUnmanagedObject(String^ param1)
{
/* Convert params, use them in some way. */
/* capture the output of this library call to the pointer defined in ManagedClass.*/
myUnmanagedObject= &(LibrayObject.LibraryMethod1());
}
void ManagedClass::UseUnManagedObject()
{
/* This function will pass the Unmanaged object into
* a library function which will do some work on it.
*/
LibraryObject.LibraryMethod2(*myUnmanagedObject);
/* Whoops! System.AccessViolationException is thrown! */
}
UnmanagedObject LibraryMethod1();
void LibraryMethod2(UnmanagedObject ¶m);
class Unmanagedclass {
public:
Unmanagedclass(const char* arg) {}
void mumble() {}
};
有趣的是,如果我在LibraryMethod1之后立即调用CreateUnmanagedObject中的LibraryMethod2,它就可以正常工作。但是在CreateUnmanagedObject退出后,myUnmanagedObject指向的内存似乎丢失了
有人能看出发生这种情况的原因吗
编辑:库声明如下所示:
public ref class ManagedClass
{
public:
ManagedClass();
void CreateUnmanagedObject(String^ param1);
void UseUnmanagedObject();
UnmanagedObject *myUnmanagedObject;
}
void ManagedClass::CreateUnmanagedObject(String^ param1)
{
/* Convert params, use them in some way. */
/* capture the output of this library call to the pointer defined in ManagedClass.*/
myUnmanagedObject= &(LibrayObject.LibraryMethod1());
}
void ManagedClass::UseUnManagedObject()
{
/* This function will pass the Unmanaged object into
* a library function which will do some work on it.
*/
LibraryObject.LibraryMethod2(*myUnmanagedObject);
/* Whoops! System.AccessViolationException is thrown! */
}
UnmanagedObject LibraryMethod1();
void LibraryMethod2(UnmanagedObject ¶m);
class Unmanagedclass {
public:
Unmanagedclass(const char* arg) {}
void mumble() {}
};
您是否没有使用临时变量的地址?如果
LibraryObject.LibraryMethod1()
返回某个值的副本,然后获取局部变量的地址,该地址在方法末尾超出范围。事后使用该地址是未定义的行为,在这种情况下会导致访问冲突 不确定你真正的问题是什么,但看起来完全错了。托管包装应该与非托管包装非常相似。让我们从非托管声明开始工作,如下所示:
public ref class ManagedClass
{
public:
ManagedClass();
void CreateUnmanagedObject(String^ param1);
void UseUnmanagedObject();
UnmanagedObject *myUnmanagedObject;
}
void ManagedClass::CreateUnmanagedObject(String^ param1)
{
/* Convert params, use them in some way. */
/* capture the output of this library call to the pointer defined in ManagedClass.*/
myUnmanagedObject= &(LibrayObject.LibraryMethod1());
}
void ManagedClass::UseUnManagedObject()
{
/* This function will pass the Unmanaged object into
* a library function which will do some work on it.
*/
LibraryObject.LibraryMethod2(*myUnmanagedObject);
/* Whoops! System.AccessViolationException is thrown! */
}
UnmanagedObject LibraryMethod1();
void LibraryMethod2(UnmanagedObject ¶m);
class Unmanagedclass {
public:
Unmanagedclass(const char* arg) {}
void mumble() {}
};
那么你的包装应该像这样:
#pragma managed(push, off)
#include "unmanagedclass.h"
#pragma managed(pop)
using namespace System;
using namespace System::Runtime::InteropServices;
public ref class ManagedWrapper
{
Unmanagedclass* instance;
public:
ManagedWrapper(String^ arg) {
IntPtr mem = Marshal::StringToCoTaskMemAnsi(arg);
instance = new Unmanagedclass((char*)(void*)mem);
Marshal::FreeCoTaskMem(mem);
}
~ManagedWrapper() {
delete instance;
instance = 0;
}
!ManagedWrapper() {
delete instance;
}
void mumble() {
instance->mumble();
}
};
这里的诀窍是非托管类的实例是包装器中的指针。只需将托管方法调用委托给非托管方法调用。是的,一些带字符串的hokeypokey,如图所示。并确保在用户或垃圾回收器访问此本机实例时将其删除。您正在获取指向on-stack temp变量的指针。幸运的是,如果你一个接一个地调用这些方法,它会指向一些东西 <>我在C++多年的代码中用C++编写了一些东西,并且必须告诉你,现在我有同样的问题。
简言之,不要将临时创建的内容的地址存储在指针中以备将来使用。我不在练习C++了。如果我必须使用&字符获取地址,那么这意味着LibraryMethod1将返回一个值,而不是像我所想的那样返回一个对象引用。啊!你能发布库方法的C++签名吗?嗯,下投票不是我期望的。想解释一下问题是什么吗?@nobugz:+1。祝贺你取得10万英镑的成绩。完全支配:代码示例为OThanks。这绝对是我从一开始就应该做的。