2013-09-24 90 views
0

後續至PInvoke byte array to char not behaving properly in 64 bit。 (過時的問題和我的懷疑是錯誤的,因此標題和描述不合適)。當編譯爲64位時,P/Inovke參數偏移32位

我使用P/Invoke從C#調用C++代碼。我將C#和C++項目設置爲在VS的構建配置中以x64構建。當我運行該程序,P的參數/調用呼叫是由32位移位如下

C# : |Parameter 1|Parameter 2|Parameter 3|Parameter 4| 
      |   |   |   |   | 
      V   V   V   V   V 
C++:    |Parameter 1|Parameter 2|Parameter 3|Parameter 4| 

所以,如果我通過1,2,3,4-從C#側,C++的側接收2, 3,4,垃圾。

我已經解決了這個問題,在C#參數前面傳遞了一個額外的int值而不改變C++端。這將參數偏移32位,並重新對齊它們,程序完美地工作。

有誰知道什麼是造成這種奇怪的偏移量和正確的方法來糾正它?

下面是一個簡化的示例示出了我的方法簽名

C#側:

[DllImport(@"C:\FullPath\CppCode.dll", EntryPoint = "MethodName", 
CallingConvention = CallingConvention.Cdecl))] 
private static extern bool MethodName(parameters); 

C++側:

extern "C" __declspec(dllexport) 
bool CppClass::MethodName(parameters) 

我懷疑,因爲參數是關閉的32位,有可能是某種事情並沒有真正在64位上完成。也許在調用方法時,有一個在變量之前傳遞的隱式指針?如果這只是C#端的一個32位指針,並且C++期望一個64位指針,那可能會導致這種偏移情況,但我不確定。

+1

您不應該顯示簡化版本。魔鬼在於細節:-)。另外,MethodName不應該是C++類的實例方法,而應該是類似C的函數。 –

+0

所以應該是一個靜態方法?或者我應該把它從課堂上分離出來? – Brian

+0

靜態應該工作我猜,這是因爲當有人調用該方法時,第一個參數是一個指向類實例的指針,所以你需要擺脫這個。 –

回答

1

MethodName不應該是一個類實例方法,因爲第一個字節(x86世界中的4個,x64世界中的8個)將用於非託管世界中的類實例指針。

所以,它應該是一個靜態方法(或C風格的方法)。