【问题标题】:Capturing return type of unmanaged class using C++/CLI使用 C++/CLI 捕获非托管类的返回类型
【发布时间】:2011-08-06 12:24:39
【问题描述】:

我的本​​机 dll 中有一个方法,我想使用它。该方法返回一个类型的对象,该对象也在我的本机 dll 中。我正在尝试编写一个 c++/CLI 包装器。

现在,

  • 我能否使用 C++/CLI 将返回值作为对象获取?我该如何做?
  • 我们可以存储和传递原生 C++ 对象吗?
  • 我是否需要创建自己的类似于原生 C++ 类的类?
  • 我将如何编组课程?

例如,我的原生 dll 有这些类,

class X
{
    /* some props and methods. */
};


Class Y
{
    X* someMethod();
};

我需要使用 C++/CLI 封装 someMethod 类。我可以在 CLI 中获取返回值吗?

【问题讨论】:

  • 搜索一下,我相信以前已经做过类似的事情......你可以将你的本机代码包装到一个托管的 value class 我认为。

标签: c++-cli marshalling


【解决方案1】:

从 DLL 中的导出函数返回指向 C++ 对象的指针是一个非常糟糕的主意。这是一个令人讨厌的内存管理问题,您希望客户端代码释放该对象。只有当两个 DLL 都使用 exact 与 CRT 的 DLL 版本相同的版本(/MD 编译选项)时,这才会有好的结果。如果你不能重新编译原生 DLL 然后立即停止,你就不能让它可靠地工作,否则你将来会有很大的维护问题。

Anyhoo,这两个类都需要一个包装器。它们应该类似于:

#pragma managed(push, off)
#include "xandy.h"
#pragma managed(pop)

using namespace System;

namespace something {

    public ref class XWrapper {
        X* mX;
    public:
        XWrapper(X* obj) : mX(obj) {}
        ~XWrapper() { this->!XWrapper(); }
        !XWrapper() {
            // Trouble is here!!!
            delete mX;
        }
    };

    public ref class YWrapper {
        Y* mY;
    public:
        YWrapper() { mY = new Y; }
        ~YWrapper() { this->!YWrapper(); }
        !YWrapper() { delete mY; }
        XWrapper^ someMethod() {
            return gcnew XWrapper(mY->someMethod());
        }
    };
}

【讨论】:

  • IIRC,Visual C++ /MT 选项不会让两个 DLL 共享运行时分配器,因为每个 DLL 都有自己的静态链接 C++ 运行时(因此,分配器)。选项应该是 /MD(和 /MDd 用于调试)。
猜你喜欢
  • 1970-01-01
  • 2019-01-08
  • 1970-01-01
  • 2011-10-07
  • 1970-01-01
  • 2011-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多