#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:
template
void 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.
Комментариев нет:
Отправить комментарий