繁体   English   中英

在C#中调用非托管代码并打印图像

[英]Call unmanaged code in c# and print images

我需要通过CF 2.0在具有Windows Mobile 6.5(带有打印机)的设备中打印图像,并且我具有c ++头文件,而且我还包装了调用非托管代码的类:问题:即使我读了此书,也无法弄清楚如何打印图像文档中的文档

  1. PRNAPI UINT WINAPI PrinterLoadImageFile (LPCTSTR pszFile); 说明:读取图像文件。 返回值:PRINTER_OK:成功PRINTER_ERROR:错误参数:LPCTSTR pszFile:[输入]要读取的文件
  2. PRNAPI UINT WINAPI PrinterImage (int nMode); 说明:打印图像。 返回值:PRINTER_OK:成功PRINTER_ERROR:错误参数:int nMode:[输入]设置图像打印模式。 PRINTER_IMAGE_NORMAL:200 * 200 dpi默认PRINTER_IMAGE_DOUBLEWIDTH:100 * 200 dpi PRINTER_IMAGE_DOUBLEHEIGHT:200 * 100 dpi PRINTER_IMAGE_QUADRUPLE:100 * 100 dpi
  3. PRNAPI UINT WINAPI PrinterCloseImageFile (); 说明:删除阅读图像。 返回:PRINTER_OK:成功PRINTER_ERROR:错误
  4. PRNAPI LPCTSTR WINAPI PrinterGetImageName (); 描述:获取读取的图像的名称。 返回值:LPCTSTR:[out]文件名

我确实附带了这个包装器.net代码

    [DllImport(@"PRN_DLL.dll")]
    public static extern uint PrinterCloseImageFile();
    [DllImport(@"PRN_DLL.dll")]
    public static extern uint PrinterLoadImageFile(string pszFile); 
    [DllImport(@"PRN_DLL.dll")]
    public static extern uint PrinterImage(int nMode);
    [DllImport(@"PRN_DLL.dll")]
    public static extern char[] PrinterGetImageName();

h文件的一部分:

//Close Image File
_DLL_EXPORT_ UINT WINAPI PrinterCloseImageFile();

//Load Image File
_DLL_EXPORT_ UINT WINAPI PrinterLoadImageFile(TCHAR* pszFile);
_DLL_EXPORT_ void WINAPI PrinterSetImageLeft(UINT nImageLeft);//ÇöÀç ´Ü»öºñÆ®¸Ê¸¸ Áö¿ø °¡´ÉÇÔ(2008³â11¿ù)

//Print Image
_DLL_EXPORT_ UINT WINAPI PrinterImage(int nMode);

//Get Image Name
_DLL_EXPORT_ TCHAR* PrinterGetImageName();

当我调用此代码

String path = PathInfo.GetStartupPath() + "\\logo.png";//Path to image
                NativPrinter.PrinterGetImageName();
                MessageBox.Show(NativPrinter.PrinterLoadImageFile(path).ToString());
                NativPrinter.PrinterImage(NativPrinter.PRINTER_IMAGE_NORMAL);
                NativPrinter.PrinterCloseImageFile();

我在PrinterLoadImageFile中遇到错误(错误代码1000,这意味着打印错误)。 所以任何人都可以知道我的错误在哪里。 对不起我的英语不好 。

调用PrinterLoadImageFile的明显方式可能是错误的,是您的C#代码将传递UTF-16 Unicode文本,但是本机库可能需要8位ANSI。 我们不知道是因为我们不知道TCHAR会扩展到什么。 如果是这样,则需要将IntPtr传递给PrinterLoadImageFile并手动转换为ANSI。 使用

byte[] ansiBytes = Encoding.Default.GetBytes(path);
byte[] pszPath = new byte[ansiBytes.Length + 1];//+1 for null terminator
ansiBytes.CopyTo(pszPath, 0);

转换为以字节数组存储的以NULL结尾的ANSI字符串。

然后将其复制到在非托管堆上分配的以空终止的字符串。

IntPtr ptr = Marshal.AllocHGlobal(pszPath.Length);
Marshal.Copy(pszPath, 0, ptr, pszPath.Length);

然后,您可以将其传递给PrinterLoadImageFile 处理完内存后,请使用Marshal.FreeHGlobal对其进行分配。

另一个问题是PrinterGetImageName 几乎可以肯定的是,该方法返回指向库中分配的字符串的指针。 因此,您需要将返回值声明为IntPtr ,并使用Marshal类将其转换为C#字符串。 您的代码将导致p / invoke marshaller尝试取消分配PrinterGetImageName返回的内存块,我确定那不是您想要的。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM