Передать оболочку C ++ / CLI собственного типа в другую сборку C ++ / CLI - PullRequest
4 голосов
/ 24 мая 2011

Предположим, у меня есть следующая простая оболочка NativeClassInstance.

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

Теперь я хочу создать экземпляр Wrapper из C # с Wrapper wrapper = new Wrapper() и использовать его в другой оболочке встроенных функций, которая находится в другая сборка с 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 , но вы не можете использовать с типами шаблонов, поэтому в общем случае это кажется очень ограничивающим.Я что-то пропустил?Есть ли более правильное решение?

Ответы [ 2 ]

2 голосов
/ 24 мая 2011

Мне не удалось успешно открыть нативные типы с помощью make_public, однако решение, которое я использовал, заключается в том, чтобы поместить NativeClass в свою собственную нативную DLL и затем a) ссылаться на нативную DLL из обеих сборок; и б) передать указатель на собственный класс как IntPtr.

В приведенном выше сценарии вместо 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 ...
}
1 голос
/ 24 мая 2011

Если вы используете make_public, ваше решение сделать _wrapped публичным должно работать (очевидно, что вместо этого лучше сделать публичный метод доступа).Что касается вашего комментария: «Я читал make_public, но вы не можете использовать его с типами шаблонов, поэтому в общем случае он кажется очень ограниченным».Я согласен - читайте здесь, чтобы найти обходной путь, который я использовал: http://social.msdn.microsoft.com/Forums/en-US/vclanguage/thread/b43cca63-b0bf-451e-b8fe-74e9c618b8c4/

Дополнительная информация: Лучший обходной путь для ошибки компилятора C2158: make_public не поддерживает собственные типы шаблонов

Удачи!

...