我正在尝试使用StringBuilder通过COM检索Tiff图像数据,但缓冲区在COM调用后只有3的长度。我正在将VB.NET版本转换为使用String而不是StringBuilder的C#,并且工作得很好。如果有人有任何建议或者可以给我一些好的阅读材料,我会很感激。
COM功能签名:
ULONG MTMICRGetImage (char *pcDevName, char *pcImageID, char *pcBuffer, DWORD *pdwLength
);
[DllImport("mtxmlmcr", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
public static extern Int32 MTMICRGetImage(string DeviceName, string ImageId, StringBuilder ImageBuffer, ref Int32 ImageSize);
COM致电代码:
ImageSize = Convert.ToInt32(mtValue.ToString());
TempImage = new StringBuilder(ImageSize);
mtValueSize = 9216;
RC = MTMICRGetIndexValue(mtDocInfo, "ImageInfo", "ImageURL", 2, mtValue, ref mtValueSize);
// Allocate memory for image with size of ImageSize
RC = MTMICRGetImage(ExcellaDeviceName, mtValue.ToString(), TempImage, ref ImageSize);
编辑:我认为这是由于二进制数据以及它是如何编组的,字符串中的字符4是一个空字符。根据Marshal.PtrToStringAuto()/ Marshal.PtrToStringUni(),复制第一个空字符的所有字符。
答案 0 :(得分:1)
我明白了。该问题是由于空字符在Marshalled时终止StringBuilder引起的。相反,我不得不使用IntPtr并直接从内存中读取字节为字节数组。请参阅下面的解决方案。
[DllImport("mtxmlmcr", CharSet = CharSet.Ansi, SetLastError = true, ExactSpelling = true)]
static extern Int32 MTMICRGetImages(string DeviceName, ref MagTekImage MagTekGImages, ref Int32 TotalImages);
//
// Allocate memory for image with size of imageSize, because the image
// data has null characters (which marshalling doesn't like), we must
// get the memory location of the char* and read bytes directly from memory
//
IntPtr ptr = Marshal.AllocHGlobal(imageSize + 1);
RC = MTMICRGetImage(ExcellaDeviceName, mtValue.ToString(), ptr, ref imageSize);
// Copy the Image bytes from memory into a byte array for storing
byte[] imageBytes = new byte[imageSize];
Marshal.Copy(ptr, imageBytes, 0, imageSize);
Marshal.FreeHGlobal(ptr);