2011-09-03 60 views
0

我使用下面的DllImport:參數從C#代碼錯誤地傳遞到C++ DLL

[DllImport(@"someDLL.dll", CallingConvention = CallingConvention.Cdecl)] 
private static extern UINT64 someFunc(int arga, int argb, int argc); 

我打電話的功能如下:

someFunc(0,0,1); 

H中的文件I聲明函數:

extern "C" __declspec(dllexport) UINT64 someFunc(int arga, int argb, int argc); 

CPP:

UINT64 someFunc(int arga, int argb, int argc) 
{ 
    ... 
} 

在C++代碼中,我收到奇怪的值(例如1218628,20140292,1219020)。

任何想法爲什麼?

+1

您可以看到C#代碼和C++代碼,但無法解決這個問題。您希望我們只能從C#代碼中完成它是不公平的。你在interop上標記了它,這意味着互操作有兩個方面。你爲什麼拒絕我們進入其中一方? –

+1

添加的代碼c –

+1

這是一個會員函館?如果沒有,那麼我可以看到沒有錯。 C++肯定使用cdecl嗎? –

回答

0

您沒有顯示C++代碼,所以我沒有在代碼中看到問題。所以,我嘗試自己重新創建它。我創建了一個調用DLL的C#WPF項目。

C#:

 
     [DllImport(@"c:\users\owner\documents\visual studio 2010\Projects\MyDll\Release\MyDll.dll", 
      CallingConvention = CallingConvention.Cdecl)] 
     private static extern UInt64 someFunc(int arga, int argb, int argc); 

     private void DoIt_Click(object sender, RoutedEventArgs e) 
     { 
      UInt64 val = someFunc(0, 0, 1); 
      ResultLabel.Content = val.ToString(); 
     } 

C++ DLL:

 
extern "C" __declspec(dllexport) unsigned __int64 someFunc(int arga, int argb, int argc) 
{ 
    CString s; 
    s.Format(L"%d\t%d\t%d", arga, argb, argc); 
    AfxMessageBox(s); 
    return arga + argb + argc; 
} 

從C++消息框顯示0 0 1如預期和C#代碼獲取1返回正常。

+0

如果有問題,我從dumpbin/exports中獲取EntryPoint文本MyDLL.dll – jschroedl

+0

使用extern「C」來避免修改,就像問題 –

+0

中的代碼一樣,這也適用於我。還調整了我的代碼以使用未簽名的__int64。所以看起來我們看不到問題。 – jschroedl

0

如果可以,使用__stdcall而不是__cdecl,在__stdcall中是執行堆棧清理的C DLL,並且是使用Windows C dll的標準方式。

在C代碼中指定調用約定也是一種很好的行爲,爲了可讀性和C++項目設置都可以指定缺省情況下使用的調用約定。

嘗試明確地設置__cdecl,也許C++編譯器使用__stdcall編譯它。

extern "C" __declspec(dllexport) UINT64 __cdecl someFunc(int arga, int argb, int argc); 
+1

只要你在兩邊使用相同的東西,你使用哪一個並不重要。 –