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

时间:2013-02-02 11:45:18

标签: c# c++ pinvoke compact-framework2.0

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

  1. PRNAPI UINT WINAPI PrinterLoadImageFile (LPCTSTR pszFile); 描述:读取图像文件。返回:PRINTER_OK:成功 PRINTER_ERROR:错误参数:LPCTSTR pszFile:[in] file to read
  2. PRNAPI UINT WINAPI PrinterImage (int nMode);描述:打印 图片。返回:PRINTER_OK:成功PRINTER_ERROR:错误参数: int nMode:[in]设置图像打印模式。 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]的名字 文件
  5. 我确实带了这个包装.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表示打印错误)。 所以任何人都有任何线索在哪里是我的错误。 对不起我的英文。

1 个答案:

答案 0 :(得分:0)

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

转换为以空字符结尾的ANSI字符串,存储在字节数组中。

然后将其复制到在非托管堆上分配的以null结尾的字符串。

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

然后,您可以将其传递给PrinterLoadImageFile。完成内存后,请使用Marshal.FreeHGlobal解除分配。

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