簡體   English   中英

從托管C#回調非托管代碼

[英]Callback unmanaged code from managed C#

這里有一段歷史課。 我正在研究舊的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進行交互。

謝謝!

如果其他答案無法解決,您可以隨時編寫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 /調用您心臟的內容( void *如果移至64位,則應成為IntPtr以確保兼容性)。 有時候,如果我真的很雄心勃勃,我實際上會在P / Invokes周圍編寫一個C#包裝程序,以對事物進行“重新分類”。

我已經忘記了.NET 1. *,但是:

定義必要的接口,並將.NET組件注冊為COM對象。 .NET實用程序通常會提供合理的封送處理代碼。

如果可能,請從C ++應用程序作為COM對象訪問它們,而根本不使用任何托管C ++。 (使用接口指針而不是回調函數)。

如果不選擇COM,請使用.NET Reflector來查看自動生成的互操作程序集內部發生的情況-這可能有助於您了解如何手動執行同一操作。

我從沒有嘗試過,但是您是否檢查過.net1中肯定存在的RuntimeMethodHandle結構?

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

以及從MSDN的描述.net2 Marshal :: GetDelegateForFunctionPointer方法中復制粘貼的內容

在.NET Framework的1.0和1.1版本中,可以將代表托管方法的委托傳遞給非托管代碼作為函數指針,從而允許非托管代碼通過函數指針調用托管方法。 非托管代碼也有可能將該函數指針傳遞回托管代碼,並且該指針已正確解析為基礎托管方法。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM