简体   繁体   English

从托管C#回调非托管代码

[英]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.

相关问题 从非托管代码回调到托管代码 - Callback from Unmanaged code to managed 将数据从非托管代码 (C) 传递到托管代码 (C#) - passing data from unmanaged code (C) to managed code (C#) 从托管 C# 回调到非托管 C++ 代码 - Callbacks from Managed C# to Unmanaged C++ Code 从托管C#应用程序调用非托管代码的缺点 - Disadvantages of calling unmanaged code from a managed C# app 将C#回调函数传递到托管和非托管C ++库中 - Passing a C# callback function into managed and unmanaged C++ libraries 从C#windows服务调用C ++ DLL(非托管代码)(用托管代码编写) - Calling a C++ dll (unmanaged code) from a C# windows service (written in managed code) 从C#调用非托管C ++库(dll):如何在托管代码和非托管代码之间正确传递数据 - Calling unmanaged C++ library (dll) from C# : How to properly pass data between managed and unmanaged code 是否可以使用来自托管代码的 C# 反射来调用非托管代码? - Is it possible to call unmanaged code using C# reflection from managed code? 从托管C#代码中使用SAFEARRAY ** ppsa参数调用非托管C方法 - Calling a unmanaged C method with a SAFEARRAY **ppsa argument from managed C# code 从非托管C ++代码调用托管C#组件,我该如何定义配置 - calling managed c# component from unmanaged c++ code, how do i define config
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM