Pointers C++/CLI指针问题=有趣! 我一直把一组旧的C++代码转换成C++/CLI代码,我想我已经把自己编码成一个角落。 我的目标是采用一个非托管C++库和一组头文件,并将它们的功能暴露给C语言解决方案。通过互联网阅读,实现这一目标的标准方法是: < LI>创建两个C++类:一个托管,另一个非托管。 非托管类将在C++库中对对象进行扭曲以提供所需的功能。 托管类将在非托管类中包装所有公共方法。每个包装器方法将处理从字符串^到字符串等的必要转换

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

但是,我的场景并不复杂,所以我决定尝试在一个类中实现所有内容。我现在正在努力解决一个生成AccessViolationException的特殊问题

我的头文件如下所示:

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 &param);
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 &param);
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 &param);
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 &param);
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。这绝对是我从一开始就应该做的。