我一直在使用本机Unity插件,该插件允许用户在Windows上打印某些内容(此刻为文本)。尝试打印时堆损坏
我(编辑:OLD)码是打印文本如下:
bool PrintText(const char* pText, int pTextWidth, int pTextHeight, const char* pPrinterName) {
LPCSTR szDriver = (LPCSTR)"WINSPOOL";
TCHAR szPrinter[256];
DWORD cchBuffer = 255;
HDC hdcPrint = NULL;
HDC hdcPrintImg = NULL;
HANDLE hPrinter = NULL;
PRINTER_INFO_2 *pPrinterData;
BYTE pdBuffer[16384];
BOOL bReturn = FALSE;
LPCSTR documentFilename = "PrintTest";
LPCSTR documentText = (LPCSTR)pText;
DWORD cbBuf = sizeof(pdBuffer);
DWORD cbNeeded = 0;
pPrinterData = (PRINTER_INFO_2 *)&pdBuffer[0];
bReturn = GetDefaultPrinter(szPrinter, &cchBuffer);
if (bReturn) {
bReturn = OpenPrinter((LPSTR)pPrinterName, &hPrinter, NULL);
}
if (bReturn) {
bReturn = GetPrinter(hPrinter, 2, &pdBuffer[0], cbBuf, &cbNeeded);
ClosePrinter(hPrinter);
}
if (bReturn) {
hdcPrint = CreateDC(szDriver, (LPSTR)pPrinterName, pPrinterData->pPortName, NULL);
}
if (hdcPrint) {
Escape(hdcPrint, STARTDOC, 8, documentFilename, NULL);
TextOut(hdcPrint, pTextWidth, pTextHeight, documentText, strlen((const char*)documentText));
Escape(hdcPrint, NEWFRAME, 0, NULL, NULL);
Escape(hdcPrint, ENDDOC, 0, NULL, NULL);
DeleteDC(hdcPrint);
}
return bReturn;
}
这将文档发送到后台打印程序和打印成功,但是,我得到了VS触发断点说堆已损坏。
我很新的C++和非托管的语言一般,所以任何指针(哈哈!),我们将不胜感激:)
编辑: 一个人在工作中帮助发现问题。 最低限度代码打印文本打印机:
bool PrintText(char* inputText, int positionX, int positionY, char* printerName)
{
HDC printerDeviceContext = NULL;
HANDLE printerHandle = NULL;
BOOL bReturn = FALSE;
LPCSTR documentFilename = "PrintTest";
LPCSTR documentText = (LPCSTR)inputText;
DWORD buffer;
DWORD bytesRequired;
bReturn = OpenPrinter((LPSTR)printerName, &printerHandle, NULL);
GetPrinter(printerHandle, 2, NULL, 0, &buffer);
BYTE* printerBuffer = new BYTE[buffer]; //allocate buffer
bReturn = GetPrinter(printerHandle, 2, printerBuffer, buffer, &bytesRequired);
ClosePrinter(printerHandle);
printerDeviceContext = CreateDC(NULL, printerName, NULL, NULL);
if (printerDeviceContext)
{
Escape(printerDeviceContext, STARTDOC, 8, documentFilename, NULL);
TextOut(printerDeviceContext, positionX, positionY, documentText, strlen((char*)documentText));
Escape(printerDeviceContext, NEWFRAME, 0, NULL, NULL);
Escape(printerDeviceContext, ENDDOC, 0, NULL, NULL);
DeleteDC(printerDeviceContext);
}
delete[] printerBuffer; //free buffer
return bReturn;
}
混合'char'和'TCHAR'问题。沟通两者,并在整个过程中使用'wchar_t',以及显式的Unicode版本的Windows API(例如'GetDefaultPrinterW')。 – IInspectable
当内存管理器发现它们时,会显示有关堆损坏的消息,而这些消息并不一定就近。 – molbdnilo
@IInspectable,我同意混合'char'和'TCHAR'是一个坏主意,但硬编码Unicode API也是一个好主意。只要将所有东西都做成'TCHAR',它就可以在32位和64位构建中完美编译和工作。 –