2012-07-02 87 views
2

這是相當複雜的,所以忍受我。我有一個以Native(僅限Win32)C++編碼的第三方程序(「目標」)。作爲目標設計的一部分,它實現了一個dll插件系統。當放置在程序的「ext」目錄中時,本機DLL由目標加載。目標然後根據需要調用每個DLL提供的四種方法(Initialize,SendHook,RecvHook,Terminate)。正如你可能已經從函數名稱中猜出的那樣,插件鉤住了目標中的某些函數。我沒有源代碼到目標。本地C++使用C#DLL通過代理C++託管DLL

加載項之一是舊的和越野車 - 更不用說混淆而且相當醜陋。它是用Delphi編寫的(當然編譯爲win32 DLL)。在過去的幾個星期裏,我一直在增強並將插件翻譯成C#(我將它稱爲「擴展」)。現在已經完成了,所以我把注意力轉移到讓目標加載擴展(作爲類庫構建)。

顯然,目標(本地C++)無法直接加載擴展(託管C#)。因此,在研究之後,似乎我只需要一個「代理」DLL(使用支持CLR的VC++編寫),它將加載我的擴展,然後負責將方法調用從目標傳遞到擴展。

「簡單」。是的,沒錯。我現在比一盒彩彈樂隊裏的變色龍更困惑。我見過有關使用COM的東西,這是我需要避免的,無論是在性能和​​進程內存權限方面,因爲擴展將調用一些方法(由代理的句柄傳遞)。另外,我見過有關tlb和#import指令的內容。這似乎也不是正確的路要走。

我偶然發現這篇文章https://sites.google.com/site/srinivasnzd/csincppviacpp-cli這似乎終於在正確的軌道上。事實上,我可以從C++代理中調用我的託管C#。作爲獎勵,它出現(我還沒有能夠測試它與實際的目標呢)__declspec(dllexport)功能可以通過代理適當地調用他們的管理對手。但現在問題已經開始出現。

  • 純粹的本地進程是否可以加載啓用了CLR的DLL?我已經看到有人談論如何從啓用CLR的代碼中創建靜態庫,然後將其與純粹的本地代碼鏈接到「部分管理的,部分本地的」代理DLL。但在那個時候,混亂開始了,我不確定這個話題甚至適用於我想要做的事情。
  • 我該如何將一個DWORD地址封送到一個IntPtr(然後取消封送到C#端的函數指針)
  • 我看到了AppDomains的提及。這是我需要擔心的嗎?
  • 我假設我的代理DLL需要在相同的文件夾中運行託管擴展DLL。我需要做任何特殊的事情來加載它,或者CLR和鏈接器會照顧它嗎?
  • 除了輸出DLL之外,我還得到擴展名爲「.exp」,「.ilk」和「.lib」的文件。我認爲這些是用於靜態鏈接,我可以忽略它們,當我使用DLL?
+0

我認爲這是人們尋找*變色龍的包裝吃喝玩樂的困惑。 – dlev

+1

可憐的變色龍不知道轉什麼顏色... – Xcelled194

+0

啊,我明白了。我想最後是我感到困惑。 – dlev

回答

2

看看這template出口的C#代碼與一些幫助,而無需使用C++包裝。
不幸的是,開箱即沒有DllExport屬性,因此您需要一個C++包裝器,或者您需要修改用於執行導出的IL代碼。
編組地址不是問題,只需要注意C#端的函數指針,因爲您總是需要確保有一個引用使它們遠離GC採集器。如果保留一個靜態引用是最簡單的--GC不能在非託管代碼中看到對函數指針的引用,因此它可能會清除它。
如果你有幾個c#模塊,應用領域將會很重要 - 如果這些模塊共享相同的代碼,它將變成更多的問題。
exp來自鏈接器,ilk和lib與鏈接器有關,因此我希望您不需要複製它們,但在調試時可能需要它們。

+0

哇。我印象深刻...這與廣告中的完全一樣。但是,現在,無論何時我嘗試使用擴展加載表單(當然是在另一個線程上),目標都會凍結。根本沒有錯誤信息....在我開新問題之前有任何想法? – Xcelled194

+0

加載表單是什麼意思? Windows窗體? – weismat

+0

是的,請看這裏:http://stackoverflow.com/questions/11304072/c-sharp-form-from-dll-loaded-by-native-c – Xcelled194

相關問題