我正在尝试使用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 []数组?
答案 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]并得到相同的结果。