这里有一段历史课。我正在研究遗留的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代码,以便我可以捕获用户交互并让应用程序处理它们。
我查看了一些文章,例如this MSDN article,但它在VS / 2003中不起作用(编译器不喜欢委托语法)。
还有其他选择吗?我不认为我可以使用DLLImport,因为我需要与特定的应用程序实例进行交互而不是平面API。
谢谢!
答案 0 :(得分: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#中调用你的心脏内容( void *这个应该成为一个IntPtr,以确保你移动到64位时的兼容性)。有时,如果我真的雄心勃勃,我实际上会在P / Invokes周围编写一个C#包装器来“重新分类”这个东西。
答案 1 :(得分:0)
我已经忘记了.NET 1. *,但是:
定义必要的接口并将.NET组件注册为COM对象。 .NET实用程序通常会提供相当好的编组代码。
如果可能,从C ++应用程序访问它们作为COM对象,根本不需要任何托管C ++。 (使用接口指针而不是回调函数)。
如果COM不是一个选项,请使用.NET Reflector查看自动生成的互操作程序集内部发生了什么 - 这可能会让您深入了解如何手动执行相同操作。
答案 2 :(得分:0)
我自己从未尝试过,但你检查过.net1中肯定存在的RuntimeMethodHandle结构吗?
SomeDelegate Handler = new SomeDelegate(SomeMethod);
IntPtr HandlerPtr = Handler.Method.MethodHandle.GetFunctionPointer();
来自MSDN描述的一些复制粘贴.net2 Marshal :: GetDelegateForFunctionPointer 方法:
在.NET Framework的1.0和1.1版中,可以将表示托管方法的委托作为函数指针传递给非托管代码,允许非托管代码通过函数指针调用托管方法。非托管代码也可以将该函数指针传递回托管代码,并且指针已正确解析为基础托管方法。