2014-03-25 50 views
1

我試圖使用PInvoke在第三方DLL中調用一個方法,該方法填充輸出緩衝區,然後使用套接字將其發送到服務器。該方法具有以下特徵:使用P/Invoke通過套接字發送簽名字符

int APIENTRY loop(HANDLE handle,char *in,unsigned int inLength, 
        char *out,unsigned outBufferSize, 
        unsigned *outLength); 

如果我把這種從一個C++應用了緩衝液含有用下面的代碼簽名的值然後被髮送到服務器:

send(mysocket,outbuffer,outbytes,0); 

的問題,我有沒有那個socket.Send在C#似乎不支持sbyte [],我相信是相當於C++非託管字符*? 在我的C#程序中,我有以下幾點:

[DllImport("vbftam.dll")] 
    public static extern int loop(IntPtr handle, IntPtr inputBytes, uint inLength, IntPtr outputBytes, uint outBufferSize, out uint outLength); 

然後我用下面的代碼調用該方法:

var outBufferPtr = Marshal.AllocHGlobal(256); 
loop(handle, inBufferPtr, inBytes, outBufferPtr, 256, out outbytes) 
byte[] myArray = new byte[256]; 
Marshal.Copy(outBufferPtr,myArray, 0, 256); 

如果我把myArray的服務器,我回去的響應不是我期待我認爲是因爲myArray未簽名,並且服務器期望有符號值。

我用下面的代碼來生成signedArray,但是socket.Send沒有一個需要sbyte []的重載。

sbyte[] signedArray = new sbyte[myArray.Length]; 
Buffer.BlockCopy(myArray, 0, signedArray, 0, myArray.Length); 

這可能在C#中嗎?如果是的話,我將如何使用套接字發送這個sbyte []數組?

+0

使用sbyte []沒有意義,您實際上沒有解釋數據。數組聲明不會改變數據。因此只需使用byte []並轉發它,只有接收數據的應用程序關心它的外觀。 –

+0

非常感謝您的回答,因爲您的回答讓我走上正軌。一旦我收到服務器的響應,我再次調用循環方法,通過inBufferPtr傳遞響應。我需要將響應轉換爲已解決問題的簽名數組。 – user3459742

回答

0

您可以將您的簽名數組轉換爲無符號數組,然後照常發送。底層的數據看起來是一樣的,它只是計算機如何處理它受到無符號或有符號屬性的影響。 Here在右邊的表中,您可以看到兩個表示都具有相同的位順序。考慮下面的帶符號的字節數組:[0,-1,1,127]你實際上可以發送它的無符號轉換[0,255,1,127]並得到相同的結果。

+0

非常有趣,這甚至沒有跨過我的腦海! – aevitas

0

由於Socket類不支持發送符號字節,你需要將自己的sbyte陣列轉換成支持同一範圍,如int類型,併發送跨到您的服務器。然後,在服務器端,將該陣列轉換回sbyte[]

1

你也可以使用一個結構是這樣的:

[StructLayout(LayoutKind.Explicit, Pack = 1)] 
private struct Union 
{ 
    [FieldOffset(0)] 
    public byte[] ByteArray; 
    [FieldOffset(0)] 
    public sbyte[] SByteArray; 
} 

分配SByteArray您陣列,然後通過ByteArray的插座。這種方式在轉換之間沒有任何開銷,但是,這不是可驗證的,可能在任何規範中都沒有很好的定義,所以它只應用於您確實需要非常高效的情況。