【问题标题】:Pass a C++/CLI wrapper of a native type to another C++/CLI assembly将本机类型的 C++/CLI 包装器传递给另一个 C++/CLI 程序集
【发布时间】:2011-08-31 10:44:54
【问题描述】:

假设我有以下 NativeClassInstance 的简单包装器。

public ref class Wrapper
{
private:
    NativeClass *_wrapped;
public:
    Renderer()
    {
        _wrapped = new NativeClass();
    }
    ~Renderer()
    {
        delete _wrapped;
    }
    operator NativeClass*()
    {
        return _wrapped;
    }
}

现在,我想用 Wrapper wrapper = new Wrapper() 从 C# 创建一个 Wrapper 的实例,并将它用在另一个本地功能包装器中,该包装器位于 another 程序集中,带有 Helper.Foo(wrapper)(没有其他功能没有什么奇怪的与另一个程序集中的包装类直接相关,IMO):

// Utilities is in another Assembly
public ref class Helper
{
public:
    static Foo(Wrapper ^wrapper)
    {
        // Do something in native code with wrapper->_wrapped
    }
}

隐式用户转换的结果是:

  • 无法访问候选函数

如果我将 _wrapped 公之于众:

  • 无法访问类中声明的私有成员...

现在,我了解到本机类型的可见性在程序集之外是 private。那么,我应该如何在它定义的程序集之外的本机代码中使用包装的实体?我读过make_public,但你不能使用模板类型,所以在一般情况下它似乎非常有限。我错过了什么吗?有没有更正确的解决方案?

【问题讨论】:

    标签: assemblies c++-cli wrapper native visibility


    【解决方案1】:

    我无法使用make_public 成功公开本机类型,但是我使用的解决方案是将NativeClass 放入它自己的本机 DLL 中,然后 a) 从两个程序集中引用本机 DLL; b) 将指向本机类的指针作为IntPtr 传递。

    在上述情况下,您可以使用诸如 operator NativeClass* 之类的属性,而不是 operator NativeClass*

    property IntPtr WrappedObject {
        IntPtr get() { return IntPtr(_wrapped); }
    }
    

    然后您可以通过

    在您的助手程序集中检索NativeObject
    static void Foo(Wrapper ^wrapper)
    {
        NativeObject *_wrapped
            = static_cast<NativeObject*>(wrapper->WrappedObject.ToPointer());
        // ... do something ...
    }
    

    【讨论】:

    • 是的,我已经考虑过(并且肯定在其他地方读过)这个解决方案。现在我在你的回答中看到了它看起来并不那么糟糕......
    【解决方案2】:

    如果您使用 make_public,则将 _wrapped public 的解决方案应该可以工作(显然最好改为使用公共访问器)。关于您的评论“我读过 make_public 但您不能与模板类型一起使用,因此在一般情况下它似乎非常有限。”我同意——在这里阅读我使用的解决方法: http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/b43cca63-b0bf-451e-b8fe-74e9c618b8c4/

    更多相关信息: Best workaround for compiler error C2158: make_public does not support native template types

    祝你好运!

    【讨论】:

    • 大声笑,我已经看到你的答案了!我认为有一次我应该接受这个限制及其解决方法。
    • 实际上,这不是一个糟糕的解决方法。本机 wrappER 类型(到本机 wrappED 类型)上的显式转换运算符也可能有助于提高可用性。
    • 引用 msdn 网站上的解决方案。 “所以创建一个本地类 VectorOfNativeB 并在其中存储指向 std::vector 的指针/引用。将此类放入 B 并使用 make_public 杂注将其公开。更改 GetMgdClassB 方法以获取指针/引用到这个本地班级”,Mike Danes(微软社区贡献者,版主)。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-12-29
    • 2015-09-17
    • 1970-01-01
    相关资源
    最近更新 更多