我有一个DLL,它的存在仅仅是为了向Python公开一些打印机API函数。其中一种方法如下:
extern "C" DOEXPORT const wchar_t* P_EnumPrintersW() {
DWORD dwneeded(0), dwreturned(0);
BOOL test = ::EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
NULL,
4,
NULL,
0,
&dwneeded,
&dwreturned);
std::vector<byte> printbuf;
printbuf.resize(dwneeded);
test = ::EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS,
NULL,
4,
&printbuf[0],
printbuf.size(),
&dwneeded,
&dwreturned);
PRINTER_INFO_4* print4 = static_cast<PRINTER_INFO_4*>((LPVOID) &printbuf[0]);
wstring result;
for (DWORD i = 0; i < dwreturned; ++i) {
result += L",";
result += print4[i].pPrinterName;
}
return result.c_str();
}
这通常如预期的那样工作,我可以在python世界中使用以下代码调用它:
^{pr2}$我通常希望dllopts看起来像这样:
^{3}$是的,我希望空白字符串作为第一个条目,这个DLL的全部原因是为了处理具有语言支持的宽字符名称的打印机名称。在调试模式下构建DLL之前,这一切都很好。然后,我得到的不是我期望的结果,而是:
[u'\udddd\udddd\udddd...']
只有一个值,每个字符都是\udddd
。哇?是不是ctypes在调试模式下不知道如何处理dll的副作用?这是因为dll的内存映射处于调试模式的影响吗?我可以附加到我的python进程(通过它,调用它的dll)并在返回之前验证result
的值,它看起来是正确的,但它不能进入我的python程序。我有点不知所措。在
不能返回由局部变量管理的指针。当
wstring result
超出范围时,使用result.c_str()
返回的指针是未定义的行为。在解决方案示例:
你可以让p_EnumPrintersW函数接收一个指针, 使用相应的大小信息,更新指向的内存 ,然后返回指针。这个 在调用函数之前,必须在Python中分配内存。
另一种解决方案是让函数返回指向 马洛塞德记忆。你必须添加另一个API,执行 对应的
free
。相关问题 更多 >
编程相关推荐