2009-09-22 7 views
0

J'essaie de récupérer des données d'image TIFF via COM à l'aide d'un StringBuilder mais le tampon n'a qu'une longueur de 3 après l'appel COM. Je convertis une version de VB.NET en C# qui utilise une chaîne au lieu de StringBuilder et fonctionne très bien. Si quelqu'un a des suggestions ou peut me diriger vers un bon matériel de lecture, je l'apprécierais.C# Com Récupération de l'image binaire (Tiff) Données du périphérique

COM signature Fonction:

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 Code d'appel:

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); 

EDIT: Je crois que cela est dû aux données binaires et comment il est Marshalled, le caractère 4 dans la chaîne est un caractère nul. Selon Marshal.PtrToStringAuto()/Marshal.PtrToStringUni(), tous les caractères jusqu'au premier caractère nul sont copiés.

+0

Comme dans, la valeur de ImageSize est passée dans MTMICRGetImage en tant que dernier paramètre. – Justin

+0

Oui, la taille de l'image est correcte. J'ai changé la version de vb.net pour utiliser un StringBuilder et j'ai eu le même problème que le code C#. Les 3 caractères sont le début de l'en-tête du fichier tiff 'll *' (en Ascii, * = décimal pour 42). Je revérifierai la taille pour m'assurer cependant. –

+0

La taille de l'image est bonne, par StringBuilder a une capacité maximale basée sur la taille de l'image, par exemple 10754 mais après l'appel COM, il a une longueur de 3 seulement. –

Répondre

1

Je l'ai compris. Le problème a été provoqué en raison des caractères null terminant le StringBuilder lors d'être Marshalled. Au lieu de cela, j'ai dû utiliser un IntPtr et lire les octets directement hors de la mémoire dans un tableau d'octets. Voir ci-dessous pour la solution. Etes-vous sûr que ImageSize est> 3?

[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); 
+0

Inspiration de http://bytes.com/topic/c-sharp/answers/251820-stringbuilder-help –

Questions connexes