Мне нужно напечатать изображение на устройстве с Windows Mobile 6.5 (с принтером) через CF 2.0, и у меня есть файл заголовка c ++, и я также упаковал класс, который вызывает неуправляемый код:
Проблема: я не могу понять, как я могу печатать изображения, даже если я читаю этот документ
В документации
и я пришел с этим кодом оболочки .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);
преобразовать в строку ANSI с нулевым символом в конце, сохраненную в байтовом массиве.
А затем скопируйте его в строку с нулевым символом в конце, расположенную в неуправляемой куче.
IntPtr ptr = Marshal.AllocHGlobal(pszPath.Length);
Marshal.Copy(pszPath, 0, ptr, pszPath.Length);
Затем вы можете передать это PrinterLoadImageFile
, Когда вы закончите с памятью, освободите ее Marshal.FreeHGlobal
,
Другая проблема PrinterGetImageName
, Почти наверняка это возвращает указатель на строку, которая размещена в библиотеке. Таким образом, вам нужно объявить возвращаемое значение как IntPtr
и использовать Marshal
класс для преобразования в строку C #. Ваш код приведет к попытке маршаллера p / invoke освободить блок памяти, возвращаемый PrinterGetImageName
и я уверен, что это не то, что вы хотите.
Других решений пока нет …