【问题标题】:Concatenating a string and byte array in to unmanaged memory将字符串和字节数组连接到非托管内存
【发布时间】:2010-04-07 16:55:13
【问题描述】:

这是我的last question 的后续。

我现在有一个byte[] 的位图图像值。最终,我会将一个字符串传递给格式为String.Format("GW{0},{1},{2},{3},", X, Y, stride, _Bitmap.Height) + my binary data; 的打印后台处理程序,我正在使用来自hereSendBytesToPrinter 命令。

这是我目前发送到打印机的代码

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

我的问题是我不知道如何将我的数据附加到字符串的末尾。任何帮助将不胜感激,如果我这样做完全错误,我可以采用完全不同的方式(例如,在移动到非托管空间之前以某种方式将二进制数据连接到字符串上。

附: 作为第二个问题,ReAllocCoTaskMem 会在调用之前将其中的数据移动到新位置吗?

【问题讨论】:

    标签: c# memory unmanaged concatenation


    【解决方案1】:

    我建议您尽量留在托管空间中。使用 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);
    

    【讨论】:

    • 我是否不需要将缓冲区移出调用的托管代码。微软为 kb 提供的示例使用 public static extern bool WritePrinter(IntPtr hPrinter, IntPtr pBytes, Int32 dwCount, out Int32 dwWritten);
    • 编组字节数组的方法有很多种。我没有测试它,但是在方法签名中用byte[]替换IntPtr应该可以。
    • 我使用了你的方法,但是我遇到了一个后续问题。 stackoverflow.com/questions/2595393
    猜你喜欢
    • 2011-11-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-01-06
    相关资源
    最近更新 更多