2012-12-20 62 views
0

我寫了下面C++代碼來創建win 32 Dynamic link library收到錯誤,以PInvoke的函數調用不平衡棧

#include <windows.h> 
#include <some.h> 

unsigned char m_KSN[10]; 
unsigned char m_inintial_key[16]; 
unsigned char initial_key[16]; 

extern "C" __declspec(dllexport) unsigned char* OnDecryption(LPCTSTR stringKSN, 
    LPCTSTR BDK){ 
     for(i=0;i<10;i++){ 
      m_KSN[i]=asctohex(stringKSN[2*i],stringKSN[2*i+1]); } 
     for(i=0;i<16;i++){ 
    m_inintial_key[i]=asctohex(BDK[2*i],BDK[2*i+1]);} 
     GetInitalKey(m_KSN, m_inintial_key, initial_key); 
     // GetInitialKey function written in `.lib` file. Data type of (Byte*a Byte* b Byte* c) 
    return initial_key; 
    } 

凡爲我的C#代碼:

static class DecryptionDll 
{ 
    public String BDK = "0111111119ABCDEFFEDCBA9877777777"; 
    public String KSN = "62994900380000C00329"; 

    internal static class UnsafeNativeMethods 
    { 
     const string _dllLocation = "finalTest.dll"; 
     [DllImport(_dllLocation)] 
     public static extern byte OnDecryption(string ksn, String bdk); 
    } 
} 

我把dll文件在我目前的目錄中,我通過以下命令得到:

String path = System.IO.Path.GetDirectoryName(System.Reflection.Assembly. 
GetExecutingAssembly().Location); 

它顯示我my debug文件夾是當前路徑。所以我把dll放在那裏。我也得到了很多帖子,但無法理解PInvoke的情況。 請幫助我..

請告訴我,我應該怎麼做改變c++c#代碼來調用寫在dll方法。

我非常抱歉有這麼多的修改。它發生是因爲我的連接速度慢

+0

可能是'cdecl'與'stdcall'問題。 – CodesInChaos

+2

您需要確保雙方的呼叫約定相符。無論是在C代碼和'CallingConvention = CallingConvention.Cdecl'在p添加'__cdecl' /調用屬性,否則'__stdcall1'和'CallingConvention = CallingConvetion.StdCall'。 –

+0

@BenVoigt我應該在extern「C」__declspec(dllexport)之後添加_cdecl嗎? –

回答

0

您的C++函數被聲明爲返回一個指向unsigned char數據的指針,但從不返回任何內容。它編譯出來是令人驚訝的;鑑於該聲明和沒有「返回」聲明的事實,似乎應該從C++編譯器中獲取錯誤。

我想你的意思是返回m_KSN的地址,但是那個變量聲明在哪裏?從命名看,它看起來像一個成員變量,但該函數似乎不是一個成員函數。

在您編輯後,事情仍然沒有排隊。名稱中有很多變量,暗示它們是成員變量。但目前沒有班級,我們也沒有看到這些變量的聲明。

在C#中,你聲明你的函數返回一個字節。您正在返回一個指向C++中的字節的指針,這通常意味着您要返回一整個字節數組。你的C#聲明應該更像這樣嗎?

public static extern byte [] OnDecryption(string ksn, String bdk); 

您的C++代碼假設傳遞字符串的長度並且從不測試它們。你可能會走進一個空字符串,或者比你想象的更短(或更長)的字符串。或者沒有有效的十六進制字符的字符串。

你能跟我們分享爲什麼你特別相信你的「功能不平衡」?你的意思是你的功能是什麼?

我看你已經取得了一些進一步的編輯,這解決您以前使用m_陣列背後的玄機 - 儘管你有兩個聲明爲同一m_initial_key變量。 m_ninitial_key是否與m_inintial_key內在不同?或者是錯字?

但其他問題和問題仍然存在。我想還有一個問題是關於GetInitialKey()函數。這不是一個衆所周知的Windows函數,所以我們無法猜測它沒有它的源代碼的功能;也許它期望參數不同於你傳遞的參數,這實際上是導致問題的原因。

既然你想返回一個指向unsigned char數組的指針,你可以使用IntPtr來完成。一旦你的背部的IntPtr在C#中,使用Marshal.Copy函數出來的數據複製到byte []陣列。看起來像這樣:

internal static class UnsafeNativeMethods 
    { 
     const string _dllLocation = "..\\..\\..\\FinalTest\\debug\\finalTest.dll"; 
     [DllImport(_dllLocation, CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Unicode)] 
     public static extern IntPtr OnDecryption(string ksn, String bdk); 

     static public byte[] OnDecryptionWrapper(string ksn, string bdk) 
     { 
      byte[] data = new byte[10]; 
      IntPtr ptr = OnDecryption(ksn, bdk); 

      Marshal.Copy(ptr, data, 0, 10); 
      return data; 
     } 
    } 
+0

噢,對不起,我沒有寫全定義。讓我加入該代碼 –

+0

現在請看看它 –

+0

現在它已完成。我感到非常抱歉,此行爲 –