我有一个非常痛苦的库,目前正在接受一个C#字符串作为获取数据数组的方法; 显然,这使得针对pinvokes的编组更容易.
那么如何按字节将ushort数组转换为字符串呢?我试过了:
int i; String theOutData = ""; ushort[] theImageData = inImageData.DataArray; //this is as slow like molasses in January for (i = 0; i < theImageData.Length; i++) { byte[] theBytes = System.BitConverter.GetBytes(theImageData[i]); theOutData += String.Format("{0:d}{1:d}", theBytes[0], theBytes[1]); }
我可以这样做,但它没有完成任何远远接近理智的时间.
我该怎么办?变得不安全?通过某种IntPtr中间体?
如果它是C++中的char*,那么这将更加容易......
编辑:函数调用是
DataElement.SetByteValue(string inArray, VL Length);
其中VL是'值长度',DICOM类型,并且函数本身由SWIG生成为C++库的包装器.似乎选择的表示是字符串,因为它可以相对容易地跨越托管/非托管边界,但是在项目的整个C++代码中(这是GDCM),char*只是用作字节缓冲区.所以,当你想设置图像缓冲区指针时,在C++中它很简单,但在C#中,我遇到了这个奇怪的问题.
这是hackeration,我知道最好的办法是让SWIG库正常工作.我真的不知道该怎么做,宁愿在C#方面快速解决,如果存在的话.
P/Invoke实际上可以使用StringBuilder来创建可写缓冲区之后的大部分时间,例如在GetWindowText和相关函数上查看pinvoke.net.
但是,除此之外,数据为ushort,我假设它是以UTF-16LE编码的.如果是这种情况,您可以使用Encoding.Unicode.GetString(),但这将使用字节数组而不是ushort数组.要将ushorts转换为字节,可以分配一个单独的字节数组并使用Buffer.BlockCopy,如下所示:
ushort[] data = new ushort[10]; for (int i = 0; i < data.Length; ++i) data[i] = (char) ('A' + i); string asString; byte[] asBytes = new byte[data.Length * sizeof(ushort)]; Buffer.BlockCopy(data, 0, asBytes, 0, asBytes.Length); asString = Encoding.Unicode.GetString(asBytes);
但是,如果不安全的代码没问题,您还有其他选择.以ushort*的形式获取数组的开头,并将其强制转换为char*,然后将其传递给字符串构造函数,如下所示:
string asString; unsafe { fixed (ushort *dataPtr = &data[0]) asString = new string((char *) dataPtr, 0, data.Length); }