#net #visual_cpp #cpp_cli
У меня есть C++/cli обвязка, которая использует c++ библиотеку (которая не использует com). Меня удивил тот факт, что если явно пометить все управляемые классы атрибутом ComVisible(false), то я получаю ошибку времени исполнения "query interface was made from non com visible class". Этот интерфейс вообще com'вский. Не понимаю, как такая ситуация вообще возможна. Я предполагал, что clr использует pinvoke вызовы для таких целей. Иерархия классов следующая: Отрывок нативного кода (выпадает в process (при вызове функтора)) // Native code class NativeItem { public: templatevoid process(const std::function & functor) { for (auto location = m_components.begin(); location != m_components.end(); ++location) functor(**location); } // Some stuff std::vector m_components; }; Отрывок C++/Cli кода: inline System::IntPtr convert(System::Delegate^ source_delegate) { return System::Runtime::InteropServices::Marshal::GetFunctionPointerForDelegate(source_delegate); } [System::Runtime::InteropServices::ComVisibleAttribute(false)] public ref class ManagedItem { protected: ManagedItem(NativeItem& native_item) : m_native_item(native_item) { } private: NativeItem& m_native_item; }; public ref class DerivedManagedItem : ManagedItem { public: DerivedManagedItem(NativeItem& native_item) : ManagedItem(native_item) { } }; public ref class Manager { public: typedef void (*create_managed_item_func)(NativeItem& item); delegate DerivedManagedItem^ CreateManagedItemDelegate(NativeItem& item); DerivedManagedItem^ create_item(NativeItem& item) { return gcnew DerivedManagedItem(item); } void process(NativeItem& item) { CreateManagedItemDelegate^ create_item_delegate = gcnew CreateManagedItemDelegate(this, &Manager::create_item); create_managed_item_func function_pointer = static_cast (convert(create_item_delegate).ToPointer()); component.process(function_pointer); System::GC::KeepAlive(create_item_delegate); } };
Ответы
Ответ 1
Из комментария пользователя @AlexAkel: Проблему уже нашел. Оказывается, у меня при вызове функции в нативном коде возвращался управляемый объект. Это можно увидеть по сигнатуре делегата CreateManagedItemDelegate.
Комментариев нет:
Отправить комментарий