2013-10-08 27 views
1

我正在將一些託管C++轉換爲需要我從其他C++項目的相當多的dll調用函數的c#代碼。當你調用這些函數時,你可以指定參數的類型與C++函數所期望的不同。這是如何運行的?因爲這沒有給編譯器錯誤。例如:我的C#pinvoked函數在函數期望int參數時提供了一個datetime參數。P /在c#中調用本地C++ dll並提供不同的類型參數

+1

PInvoke不會給出編譯錯誤,因爲關於函數的唯一信息是它的PInvoke聲明 - 沒有h文件。如果參數類型不同,但參數大小相同,則可能會有效。順便說一句,你希望在1分鐘內回覆? –

回答

1

您可以躺在通過在函數[DllImport]聲明你的牙齒,很少有該PInvoke的編組可以做檢測你的聲明是不匹配的。它只知道有一個具有特定名稱的DLL文件,該文件用特定名稱導出函數。它無法說明該函數需要什麼參數,也不知道它返回了什麼。這需要更好的函數元數據,即COM類型庫或.NET程序集元數據可以提供的類型。沒有這樣的元數據存在一個普通的DLL,所以它必須假定你的聲明是準確的。

這實際上通常非常有用,它允許你將一個void *映射到一個byte []或一個IntPtr到一個引用類型引用或由ref傳遞的值類型。您可以編寫相同功能的重載。

有意使它完全錯誤,就像希望DateTime將映射到int一樣,如果幸運的話可以通過硬性崩潰來診斷。像AccessViolationException或PInvokeStackImbalance一樣。然而,沒有這種運氣的保證,它只是可能產生垃圾。

1

它不會給你一個編譯器錯誤,因爲它不會在編譯時發生。編譯器在編譯時沒有關於本地方法和類型的任何信息(除了pinvoke簽名),因此不能幫助你。在MSDN狀態

大多數PInvoke的幫助頁面:

的P/Invoke幾乎不提供編譯時錯誤報告,不是類型安全

如果你想獲得更細緻和詳細理解p/invoke,那麼你可以找到大量的文章和博客文章。這裏有幾個我建議您閱讀:

CLR Inside Out: Marshaling between Managed and Unmanaged Code

Calling Win32 DLLs in C# with P/Invoke

P/Invoke Revisited

+0

+1爲鏈接。謝謝 –

相關問題