[英]Callback unmanaged code from managed C#
Bit of a history lesson here. 这里有一段历史课。 I'm working on a legacy C++/MFC application and am trying to start a incremental modernization by pushing components written in C# (WinForms and later WPF).
我正在研究旧的C ++ / MFC应用程序,并试图通过推送用C#编写的组件(WinForms和更高版本的WPF)来启动增量式现代化。
I'm stucking using .Net/1.1 and VS/2003 for many reasons which are impossible to resolve in the near future. 由于许多原因,我坚持使用.Net / 1.1和VS / 2003,这些原因在不久的将来无法解决。
Currently, as a proof of concept, something like this works: 当前,作为概念证明,类似以下内容的作品:
#pragma push_macro("new")
#undef new
WinFormA::Form1* myform;
myform = __gc new WinFormA::Form1();
myform->ShowDialog();
#pragma pop_macro("new")
The problem I'm having is this - I need the unmanaged C++/MFC code to pass a callback pointer into the managed C# WinForm code so that I can capture user interactions and have them processed by the application. 我遇到的问题是-我需要非托管的C ++ / MFC代码才能将回调指针传递到托管的C#WinForm代码中,以便可以捕获用户交互并由应用程序对其进行处理。
I've looked at some articles such as this MSDN article but it doesn't work in VS/2003 (the compiler doesn't like the delegate syntax). 我看过一些文章,例如MSDN文章,但在VS / 2003中不起作用(编译器不喜欢委托语法)。
Are there any other options? 还有其他选择吗? I don't think I can use DLLImport since I need to interact with the specific application instance not a flat API.
我不认为我可以使用DLLImport,因为我需要与特定的应用程序实例而非平面API进行交互。
Thanks! 谢谢!
If the other answers don't work out, you could always write a C wrapper to flatten the classes. 如果其他答案无法解决,您可以随时编写C包装器来平整类。 For example, if the C++ class is:
例如,如果C ++类为:
class TheClass {
public:
TheClass(int Param);
~TheClass();
bool SomeFunction(int Param1,int Param2);
};
I'll write a wrapper: 我将编写一个包装器:
extern "C" void *TheClass_Create(int Param) {
return (void*) new TheClass(Param);
}
extern "C" void TheClass_Destroy(void *This) {
delete (TheClass*) This;
}
extern "C" bool TheClass_SomeFunction(void *This,int Param1,int Param2) {
return ((TheClass*) This)->SomeFunction(Param1,Param2);
}
Because the wrapper is straight C, you can P/Invoke in C# to your heart's content (the void *This should become an IntPtr to ensure compatibility if you move to 64-bit). 因为包装器是直接的C,所以您可以在C#中P /调用您心脏的内容( void *如果移至64位,则应成为IntPtr以确保兼容性)。 Sometimes, if I'm really ambitious, I'll actually write a C# wrapper around the P/Invokes to 're-classify' the thing.
有时候,如果我真的很雄心勃勃,我实际上会在P / Invokes周围编写一个C#包装程序,以对事物进行“重新分类”。
I already forgot .NET 1.*, but: 我已经忘记了.NET 1. *,但是:
Define necessary interfaces and register your .NET components as COM objects. 定义必要的接口,并将.NET组件注册为COM对象。 .NET utilities will usually provide reasonably good marshaling code.
.NET实用程序通常会提供合理的封送处理代码。
If possible, access them as COM objects from C++ application without any Managed C++ at all. 如果可能,请从C ++应用程序作为COM对象访问它们,而根本不使用任何托管C ++。 (Use interface pointers instead of functions for callbacks).
(使用接口指针而不是回调函数)。
If COM is not an option, use .NET Reflector to see what's going on inside auto-generated interop assemblies - this might give an insight on how to do the same thing manually. 如果不选择COM,请使用.NET Reflector来查看自动生成的互操作程序集内部发生的情况-这可能有助于您了解如何手动执行同一操作。
I have never tried it by myself, but did you check RuntimeMethodHandle struct which is definitely exists in .net1? 我从没有尝试过,但是您是否检查过.net1中肯定存在的RuntimeMethodHandle结构?
SomeDelegate Handler = new SomeDelegate(SomeMethod);
IntPtr HandlerPtr = Handler.Method.MethodHandle.GetFunctionPointer();
And some copy-paste from MSDN's description .net2 Marshal::GetDelegateForFunctionPointer Method: 以及从MSDN的描述.net2 Marshal :: GetDelegateForFunctionPointer方法中复制粘贴的内容 :
In versions 1.0 and 1.1 of the .NET Framework, it was possible to pass a delegate representing a managed method to unmanaged code as a function pointer, allowing the unmanaged code to call the managed method through the function pointer.
在.NET Framework的1.0和1.1版本中,可以将代表托管方法的委托传递给非托管代码作为函数指针,从而允许非托管代码通过函数指针调用托管方法。 It was also possible for the unmanaged code to pass that function pointer back to the managed code, and the pointer was resolved properly to the underlying managed method.
非托管代码也有可能将该函数指针传递回托管代码,并且该指针已正确解析为基础托管方法。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.