Объединение строки и байтового массива в неуправляемую память - PullRequest
0 голосов
/ 07 апреля 2010

Это продолжение моего последнего вопроса .

Теперь у меня есть byte[] значений для моего растрового изображения. В конце концов я передам строку в диспетчер очереди печати формата String.Format("GW{0},{1},{2},{3},", X, Y, stride, _Bitmap.Height) + my binary data; Я использую команду SendBytesToPrinter из здесь .

Вот мой код, чтобы отправить его на принтер

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

Моя проблема в том, что я не знаю, как сделать так, чтобы мои данные добавлялись в конец строки. Любая помощь будет принята с благодарностью, и если я делаю это совершенно неправильно, я могу пойти совершенно другим путем (например, каким-то образом связать двоичные данные со строкой до перехода в неуправляемое пространство.

P.S. Второй вопрос: переместит ли ReAllocCoTaskMem данные, которые в нем находятся, перед вызовом в новое местоположение?

1 Ответ

2 голосов
/ 07 апреля 2010

Я рекомендую вам постараться как можно больше находиться в управляемом пространстве. Преобразовать строку в байтовый массив, используя Encoding.ASCII , объединить два байтовых массива и затем вызвать собственный метод с результатом.

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

с

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