2013-12-09 26 views
3

我一直在嘗試使用非接觸式Mifare卡讀寫器提供的VB DLL,在C#DLL,但是有傳遞變量類型的問題。原來的代碼是:錯誤與「無符號字符*」進口的C#

READER_API int __stdcall RDR_LoginToSector(UCHAR Sector, UCHAR KeyType, unsigned char * KEY); 

的UCHAR可以作爲「UINT」或「字節」沒有問題,但是「無符號字符*」不工作

我試圖調用它的各類:

[DllImport("SmartReader.dll", CallingConvention = CallingConvention.Cdecl, CharSet = CharSet.Ansi)] public static extern int RDR_LoginToSector(byte Sector, byte KeyType, IntPtr KEY); 
byte[] D = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}; 
IntPtr F = new IntPtr(); 
F = Marshal.AllocHGlobal(Marshal.SizeOf(D)); 
Logged = RDR_LoginToSector((byte) 0x01, (byte)0x60, F); 

[DllImport("SmartReader.dll", CallingConvention = CallingConvention.Cdecl] public static extern int RDR_LoginToSector(byte Sector, byte KeyType, StringBuilder KEY); 
StringBuilder E = new StringBuilder(6); 
E.Append((byte)0xff); 
E.Append((byte)0xff); 
E.Append((byte)0xff); 
E.Append((byte)0xff); 
E.Append((byte)0xff); 
E.Append((byte)0xff); 
Logged = RDR_LoginToSector((byte) 0x01, (byte)0x60, E); 

[DllImport("SmartReader.dll", CharSet = CharSet.Unicode)] public static extern int RDR_LoginToSector(byte Sector, byte KeyType, byte[] KEY); 
byte[] D = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff }; 
Logged = RDR_LoginToSector((byte) 0x01, (byte)0x60, D); 

[DllImport("SmartReader.dll", CharSet = CharSet.Unicode)] public static extern int RDR_LoginToSector(byte Sector, byte KeyType, char[] KEY); 
char[] C = { (char)0xff, (char)0xff, (char)0xff, (char)0xff, (char)0xff, (char)0xff }; 
Logged = RDR_LoginToSector((byte) 0x01, (byte)0x60, C); 

我也試過用「ref」語句沒有成功。

在所有的方法中,返回值是3,這意味着登錄失敗。我使用我正在工作並可以正確記錄的Android應用程序對密鑰進行雙重檢查,並且隨附的編譯源也可以使用此密鑰。

不需要「無符號的字符*」正常工作的所有方法,就像那些以驗證卡的類型,開放的COM端口和這樣。

任何想法?

謝謝大家。

+0

1)字符串以null結尾(包括+1字符)。 2)字符串是Unicode的! E.Append((字節)爲0xFF);不會像你期望的那樣做(所有的例子都是如此)使用System.Byte就像你的第一個例子(但在末尾添加一個空終止符「0」) –

+0

@Adriano mabye一些代碼將有助於 –

+0

@MauricioGracia我'有點忙,這就是爲什麼我只發表評論! –

回答

0

由於您的C函數被聲明爲__stdcall,您應該使用匹配的調用約定:CallingConvention.StdCall

Unicode字符集不幫你。我想你想使用最後一個參數(aka,Key)的字節數組和前兩個參數的字節。 (在你的第三個例子看起來比調用約定和不必要的字符集權等)。

您也可以驗證數據的字節數組中的字節順序。我不確定它是如何用於其他領域的。

1

宣佈這一正確的方法是:

[DllImport("SmartReader.dll", CallingConvention = CallingConvention.Stdcall)] 
public static extern int RDR_LoginToSector(
    byte Sector, 
    byte KeyType, 
    [In] byte[] Key 
); 

這個聲明,您提供的本地聲明相匹配。您的嘗試使用了錯誤的調用約定,最終參數應爲byte[]。實際上,您甚至可以省略CallingConvention,因爲Stdcall是默認值。但是,明確表示不會傷害。同樣,[In]可以省略,但明確的是明智的。

返回值指示的錯誤意味着您傳遞了錯誤的參數。因爲我們不知道這個函數的細節,所以我們很難調試你傳遞的參數。

所以,我想說的是,如果你使用的P/Invoke上面,你可以從可能的故障模式列表中刪除的互操作。事實上,要完全確定你應該用C++編寫一個能夠成功調用函數的測試程序。通過這種方式,您可以調試所使用的參數,而不用擔心後面的問題是導致問題的互操作。

+0

對不起,對於扇區,參數應該是從0x00到0x0f的範圍,在KeyA的KeyType 0x60和KeyB的0x61處,密鑰本身由6個字節組成。謝謝,我會盡快測試並返回。 – user3082956

+0

我試過沒有成功,也許有bug的DLL,但是在C++中它工作。 我聯繫了供應商,他們說將發送串行命令來訪問讀者,所以我會建立自己的圖書館。 – user3082956

+0

如果您展示的是C++調用代碼,那麼很可能我們會發現不匹配 –

相關問題