C # Com Получение двоичных изображений (TIFF) данных с устройства - PullRequest
0 голосов
/ 22 сентября 2009

Я пытаюсь получить данные изображения Tiff через COM, используя StringBuilder, но длина буфера после вызова COM составляет всего 3. Я конвертирую версию VB.NET в C #, который использует String вместо StringBuilder и работает просто отлично. Если у кого-нибудь есть какие-либо предложения или я могу указать мне хороший материал для чтения, я был бы признателен.

подпись функции 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 (), копируются все символы до первого нулевого символа.

1 Ответ

1 голос
/ 23 сентября 2009

Я понял это. Эта проблема возникла из-за того, что нулевые символы завершали работу 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);
...