2010-12-12 53 views
0

我需要建立一個軟件,將讀取XML裏會有類似這樣的標記:與其他語言互操作?

<Values type="MyParser.Parser" assembly="parser.dll" /> 

通過反射做起來很簡單,但我需要找到一種方法,把任何類型的Ø語言,我的意思是,如果方法是用C編寫的,如果它是用C語言編寫的程序集,它也需要被調用。

我只能通過生成一個「exe」並將參數作爲「命令行」發送並獲取程序輸出來考慮。

我不知道這是否是最好的方式。這是「安全」嗎?還有另一種方法嗎? C#能否從另一個程序集調用方法(使用另一種語言)?

On this page it says有關「您還可以與其他語言跨平臺進行互操作」,但我不知道它的真正含義。

+1

程序集不是用C寫的.exe或dll可能是,但它們不是程序集。 – erikkallen 2010-12-12 16:58:32

回答

1

你實際上只聲明你想讀取DLL文件,而不是你想要做的值。我假設你想實例化一個類型併爲其調用一些方法。

這應該是非常容易的,如果它是一個託管DLL通過加載程序集,使用Type.GetType,然後Activator.CreateInstance。你應該爲你想實例化的類型定義一個接口,這樣你就可以得到一個很好的強類型對象來處理。如果你不能這樣做,最好的選擇可能是聲明創建的實例dynamic,然後調用你想要的方法,讓DLR做它的魔法。

現在事情變得更復雜,如果它是非託管代碼。 C和其他過程語言不會有可以實例化和調用方法的類型的概念;所以你不能使用實例化對象的相同抽象。您需要區分託管代碼和非託管代碼。

C#有DllImport這是你通常用來調用非託管代碼。這不是動態的,所以如果你事先不知道庫和過程的名字,那麼你就不能使用它。

你將能夠創建一個解決方案,使用DllImport調用Win32本機方法LoadLibraryEx(加載DLL),然後GetProcAddress獲取指向您要調用的函數的指針。然後,您可以使用Marshal.GetDelegateForFunctionPointer獲取可以調用的C#委託。完成使用非託管庫後,請不要忘記撥打FreeLibrary

0

這很大程度上取決於您嘗試與之進行互操作。如果你想從另一個.NET程序集調用一個方法,那麼你可以簡單地引用它(它寫的內容並不重要)。

我不認爲可以通過COM調用任意方法,但可以聲明每種可能的方法(與相關的Interop屬性),然後選擇一個您需要使用的依賴於配置值的方法。

如果外部程序集既不是.NET也不是COM,那麼就沒有辦法直接調用它的方法。

您可以構建解決方案的最具互操作性的方式是使用Web服務調用。

0

經典的互操作源如下:

[System.Runtime.InteropServices.DllImport("opengl32.dll", EntryPoint = "glActiveTexture", ExactSpelling = true)] 
internal extern static void glActiveTexture(int texture); 

換言之,靜態例程glActiveTexture在應用路徑發現open32.dll二進制被發現,與簽名(入口點)glActiveTexture。

有時候事情並不那麼容易。例如:

[System.Runtime.InteropServices.DllImport("opengl32.dll", EntryPoint = "glGetActiveUniform", ExactSpelling = true)] 
internal extern static unsafe void glGetActiveUniform(uint program, uint index, Int32 bufSize, [Out]Int32 length, [Out]int size, [Out]int type, [Out]StringBuilder name); 

你可以注意到參數之前[OUT]。該參數屬性用於指示例程glGetActiveUniform將輸出這些變量的數據,因爲它們實際上是該函數寫入的指針。

這是用於將互操作編組,這意味着,在進出外部例程參數的運行時副本(即:所述[OUT]屬性指示可變複製出來一旦例程作爲退出)。

上面的代碼是由我的應用程序生成的,具有函數規範(在本例中爲OpenGL)。我見過類似的代碼生成器,它需要一個C頭文件。

據我所知,你想實現這個dinamically,在運行時加載二進制文件。那麼......我會是一個艱鉅的任務,因爲必須有一種方法來爲每個庫使用伴隨配置來創建這些委託,但實際上我不知道這對任何語言都是可能的。

0

您可以使用p-invoke來執行從dll導出的C函數。