使用P / Invoke在套接字上发送带符号的char *

时间:2014-03-25 13:08:43

标签: c# sockets pinvoke

我正在尝试使用PInvoke来调用第三方DLL中的方法,该DLL填充输出缓冲区,然后使用套接字将其发送到服务器。该方法具有以下特征:

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

如果我从C ++应用程序中调用它,则out缓冲区包含有符号值,然后使用以下代码将其发送到服务器:

send(mysocket,outbuffer,outbytes,0);

我遇到的问题是在C#中socket.Send似乎不支持sbyte [],我认为它相当于C ++非托管char *? 在我的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 []数组?

3 个答案:

答案 0 :(得分:1)

你也可以使用这样的结构:

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

将SByteArray分配给您的数组,然后将ByteArray传递给Socket。这种方式在转换之间没有任何开销,但是,这不是可验证的,并且可能在任何规范中都没有很好地定义,所以它只应该用在你真正需要非常高效的情况下。

答案 1 :(得分:0)

由于Socket类不支持发送带符号字节,因此您需要将sbyte数组转换为支持相同范围的类型,例如int,并将其发送到您的服务器。然后,在服务器端,将该数组转换回sbyte[]

答案 2 :(得分:0)

您可以将已签名的数组转换为无符号数组,然后照常发送。基础数据看起来是一样的,它只是计算机如何处理受未签名或签名属性影响的数据。在右表中的Here,您可以看到两个表示具有相同的位顺序。考虑以下有符号字节数组:[0,-1,1,127]您实际上可以发送它的无符号转换[0,255,1,127]并得到相同的结果。