1

这里有点历史课。我正在开发一个遗留的 C++/MFC 应用程序,并试图通过推送用 C#(WinForms 和更高版本的 WPF)编写的组件来开始增量现代化。

我坚持使用 .Net/1.1 和 VS/2003 有很多原因,这些原因在不久的将来无法解决。

目前,作为概念证明,类似这样的工作:

#pragma push_macro("new")
#undef new

WinFormA::Form1* myform;
myform = __gc new WinFormA::Form1();
myform->ShowDialog();

#pragma pop_macro("new")

我遇到的问题是 - 我需要非托管 C++/MFC 代码将回调指针传递给托管 C# WinForm 代码,以便我可以捕获用户交互并让应用程序处理它们。

我看过一些文章,例如这个 MSDN 文章,但它在 VS/2003 中不起作用(编译器不喜欢委托语法)。

还有其他选择吗?我认为我不能使用 DLLImport,因为我需要与特定的应用程序实例而不是平面 API 进行交互。

谢谢!

4

3 回答 3

1

如果其他答案不起作用,您总是可以编写一个 C 包装器来展平类。例如,如果 C++ 类是:

class TheClass {
  public:
    TheClass(int Param);
    ~TheClass();

    bool SomeFunction(int Param1,int Param2);
};

我会写一个包装器:

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);
}

因为包装器是直接的 C,所以您可以在 C# 中 P/Invoke 到您心中的内容(如果您迁移到 64 位, void *This应该成为一个 IntPtr 以确保兼容性)。有时,如果我真的很有野心,我实际上会围绕 P/Invokes 编写一个 C# 包装器来“重新分类”事物。

于 2009-09-23T00:49:10.687 回答
0

我自己从未尝试过,但是您是否检查过.net1 中肯定存在的 RuntimeMethodHandle 结构?

SomeDelegate Handler = new SomeDelegate(SomeMethod);
IntPtr HandlerPtr = Handler.Method.MethodHandle.GetFunctionPointer();

还有一些来自 MSDN 描述 .net2 Marshal::GetDelegateForFunctionPointer Method 的复制粘贴:

在 .NET Framework 1.0 和 1.1 版本中,可以将表示托管方法的委托作为函数指针传递给非托管代码,从而允许非托管代码通过函数指针调用托管方法。非托管代码也可以将该函数指针传递回托管代码,并且该指针已正确解析到底层托管方法。

于 2009-06-26T12:20:25.083 回答
0

我已经忘记了 .NET 1.*,但是:

定义必要的接口并将您的 .NET 组件注册为 COM 对象。.NET 实用程序通常会提供相当好的编组代码。

如果可能,从 C++ 应用程序将它们作为 COM 对象访问,而无需任何托管 C++。(使用接口指针而不是回调函数)。

如果 COM 不是一个选项,请使用 .NET Reflector 查看自动生成的互操作程序集内部发生了什么——这可能会帮助您了解如何手动执行相同的操作。

于 2009-06-26T11:14:35.950 回答