使用 C++/CLI 将对象从 C# 传递到C++或将 Object^ 转换为 Object

本文关键字:Object C++ 或将 转换 CLI 对象 使用 | 更新日期: 2023-09-27 18:29:12

在C++中,我创建了这个类:

public ref class UConfig
{
    public:
       UConfig(short nr);
       ~UConfig();
       bool checkNr();
    private:
      short _nr;
}

以及将在 C# 中调用的 C++ 中的公共类:

public ref class UConfigHandler
{
    public:
        UConfigHandler(UConfig^ uConfig);        
}

然后在 C# 中,我可以这样做:

UConfig uConfig = new UConfig(1);
UConfigHandler uConfigHandler = UConfigHandler(uConfig);

在C++中,我调试它并在构造函数中:

UConfigHandler::UConfigHandler(UConfig^ uConfig)
{
    // while debugging I see that uConfig is: System::Object^
    // how to do the conversion from the uConfig to UConfig inside C++
    // I would like to do something like this but I got an exception
    UConfig myConfig = uConfig; // the program is stopped here but I dont know what is the error
}

所以,基本上我想将System::Object^ uConfig转换为本机UConfig。我该怎么做?

我用字符串^做过类似的事情:

输入为字符串^

IntPtr stringPointer = (IntPtr)Marshal::StringToHGlobalAnsi(input);
string retrievedString = string((char*)stringPointer.ToPointer());

使用 C++/CLI 将对象从 C# 传递到C++或将 Object^ 转换为 Object

您正在尝试将UConfig实例的句柄分配给UConfig对象。您已将UConfig^ uConfig声明为引用,因此只能将其分配给引用。

如果您这样做,它将等效于C++:

MyClass* mcp = new MyClass();
MyClass mcv = mcp;

换句话说,UConfigHandler构造函数应如下所示:

UConfigHandler::UConfigHandler(UConfig^ uConfig)
{
    UConfig^ myConfig = uConfig;
}

更新

你也许可以做到...您可以编组struct,因此您也应该能够编组class。我还没有这样做,但是Marshal.StructureToPtr的文档给出了一个类似的例子:

// Initialize unmanged memory to hold the struct.
IntPtr pnt = Marshal.AllocHGlobal(Marshal.SizeOf(uConfig));
// Copy the struct to unmanaged memory.
Marshal.StructureToPtr(uConfig, pnt, false);
// Create another UConfig.
UConfig myConfig ;
// Set this UConfig to the value of the 
// UConfig in unmanaged memory. 
myConfig = (UConfig)Marshal.PtrToStructure(pnt, typeof(UConfig));

但是,您无法再利用垃圾回收:您已分配非托管内存,因此您还必须释放它!如果不释放分配的内存,则会发生内存泄漏,因此不要这样做:

// Free the unmanaged memory.
Marshal.FreeHGlobal(pnt);

你想做什么?在 ConfigHandler 的构造函数中收到的UConfig^UConfig .NET 实例的完全有效句柄。没有必要编组、选角或做任何特别的事情。

所以,基本上我想将System::Object^ uConfig转换为本机UConfig。你能告诉我我该怎么做吗?

您发布的代码段中没有本机UConfig在 C# 中创建一个实例,并将其传递给存储对该实例的引用的ConfigHandler

public ref class ConfigHandler {
    Config^ mConfig;
public:
    ConfigHandler(Config^ pConfig) : mConfig(pConfig) {}
};

您甚至可以使用 C# 在完全不同的程序集中定义ConfigHandler,不会有任何区别。几乎没有,您在 C++/CLI 中定义的ConfigHandler将实现 IDisposable,但由于它不存储任何非托管资源,因此无关紧要。嗯,您是否知道您不是在编写C++而是在编写 C++/CLI,这是一个巨大的差异?