2010-04-07 16 views
0

Ceci est une suite à mon last question. J'ai maintenant un byte[] de valeurs pour mon image bitmap. Finalement, je vais passer une chaîne au spouleur d'impression du format String.Format("GW{0},{1},{2},{3},", X, Y, stride, _Bitmap.Height) + my binary data; J'utilise la commande SendBytesToPrinter de here.Concaténation d'une chaîne et d'un tableau d'octets dans une mémoire non gérée

Voici mon code jusqu'à présent pour l'envoyer à l'imprimante

public static bool SendStringPlusByteBlockToPrinter(string szPrinterName, string szString, byte[] bytes) 
{ 
    IntPtr pBytes; 
    Int32 dwCount; 
    // How many characters are in the string? 
    dwCount = szString.Length; 
    // Assume that the printer is expecting ANSI text, and then convert 
    // the string to ANSI text. 
    pBytes = Marshal.StringToCoTaskMemAnsi(szString); 
    pBytes = Marshal.ReAllocCoTaskMem(pBytes, szString.Length + bytes.Length); 
    Marshal.Copy(bytes,0, SOMTHING GOES HERE,bytes.Length); // this is the problem line 
    // Send the converted ANSI string + the concatenated bytes to the printer. 
    SendBytesToPrinter(szPrinterName, pBytes, dwCount); 
    Marshal.FreeCoTaskMem(pBytes); 
    return true; 
} 

Mon problème est que je ne sais pas comment faire mes données ajoutées à la fin de la chaîne. Toute aide serait grandement appréciée, et si je fais cela totalement faux, je vais bien d'une manière totalement différente (par exemple obtenir les données binaires concaténées sur la chaîne avant de passer à l'espace non géré). En deuxième question, ReAllocCoTaskMem va-t-il déplacer les données qui s'y trouvent avant l'appel au nouvel emplacement?

Répondre

2

Je vous recommande d'essayer de rester dans l'espace géré autant que possible Convertir la chaîne en un tableau d'octets en utilisant Encoding.ASCII , concaténer les deux tableaux d'octets, puis appeler la méthode native avec le résultat:

byte[] ascii = Encoding.ASCII.GetBytes(szString); 

byte[] buffer = new buffer[ascii.Length + bytes.Length]; 
Buffer.BlockCopy(ascii, 0, buffer, 0, ascii.Length); 
Buffer.BlockCopy(bytes, 0, buffer, ascii.Length; bytes.Length); 

... 
bool success = WritePrinter(printer, buffer, buffer.Length, out written); 
... 

avec

[DllImport("winspool.drv", EntryPoint = "WritePrinter", SetLastError = true, ExactSpelling = true, CallingConvention = CallingConvention.StdCall)] 
public static extern bool WritePrinter(IntPtr hPrinter, byte[] pBytes, int dwCount, out int dwWritten); 
+0

Ai-je pas besoin de déplacer le tampon de code managé pour l'appel. l'exemple donné par microsoft pour le kb utilise 'public static externe bool WritePrinter (IntPrtr hPrinter, IntPtr pBytes, Int32 dwCount, sur Int32 dwWritten);' –

+0

Il existe plusieurs façons de marshaler un tableau d'octets. Je ne l'ai pas testé, mais le remplacement de 'IntPtr' par' byte [] 'dans la signature de la méthode devrait fonctionner. – dtb

+0

J'ai utilisé votre méthode mais il y a une question de suivi avec un problème que j'ai rencontré. http://stackoverflow.com/questions/2595393/ –