Я пишу смешанный мост C++/CLI для смешанного режима, чтобы иметь возможность вызвать в мою библиотеку классов .NET из старого приложения на C++.Использовать собственный указатель функции для прослушивания управляемого события/маршалинга
В одном из моих классов в библиотеке .NET вы можете присоединяться к событию всякий раз, когда нужно выводить какое-либо сообщение (на консоль или что-то другое в зависимости от вызывающего приложения).
class NetApi
{
public event EventHandler<MessageEventArgs> MessageReported;
}
Для вызова этого из родного приложения C++, я определил следующий указатель/делегат мост:
typedef void(*MessageHandler)(const char* msg);
delegate void ManagedMessageHandler([MarshalAs(UnmanagedType::LPStr)] String^ msg);
Опуская из клея для подключения все (прикрепление к MessageReported
, удаление sender
из EventHandler
, и т.д .. .), вот как я создаю управляемый делегат из встроенного указателя функции:
class NetApiBridge
{
public:
void SetMessageHandler(MessageHandler handler)
{
wrappedListener = (ManagedMessageHandler^)Marshal::GetDelegateForFunctionPointer((IntPtr)handler, ManagedMessageHandler::typeid);
}
private:
msclr::auto_gcroot<NetApi^ > wrappedApi;
msclr::auto_gcroot<ManagedMessageHandler^ > wrappedListener;
// In another helper ref class in fact, but here pseudo code to simplify
void onMessageReported(Object^ sender, MessageEventArgs^ e)
{
if (!wrappedListener) { return; }
wrappedListenter(e->Message); // Send message to native function pointer
}
}
И я почти там w курица создание фиктивного C++ тестового кода:
void messageHandler(const char* s)
{
cout << s;
}
void main()
{
NetApiBridge api = new NetApiBridge();
api->SetMessageHandler(&messageHandler);
api->Measure();
delete api;
}
Все идет хорошо, события передаются правильно, за исключением .... кроме я получаю PInvokeStackImbalance
от Managed Debugging Assistant при выходе из родного обработчика, и я явно не знаю, почему?
Что не так с маршалингом const char*
как UnmanagedType::LPStr
здесь с GetDelegateForFunctionPointer
?
NB: мост C++ скомпилирован в x86, если это важно знать здесь.
Ты мой герой на сегодняшний день! Большое спасибо :) – CitizenInsane
Я верну комплимент, лучший вопрос, который я прочитал всю неделю. Очень хорошо, вы очень легко помогли вам. –