用ctypes解码Python中的C const char* 我在Python 3中使用 cType (导入代码< C>代码>)来执行C++共享库。使用以下方法将库加载到python中: smpLib = c.cdll.LoadLibrary(os.getcwd()+os.sep+'libsmpDyn.so')
其中一个函数具有用ctypes解码Python中的C const char* 我在Python 3中使用 cType (导入代码< C>代码>)来执行C++共享库。使用以下方法将库加载到python中: smpLib = c.cdll.LoadLibrary(os.getcwd()+os.sep+'libsmpDyn.so'),python,c++,c,ctypes,Python,C++,C,Ctypes,其中一个函数具有extern'C'声明const char*runSmpModel(…)。python函数原型的编码和运行方式如下: proto_SMP = c.CFUNCTYPE(c.c_char_p,...) runSmpModel = proto_SMP(('runSmpModel',smpLib)) res = runSmpModel(...) 这一切都运行得很好,但我无法解码res变量并获取由CrunSmpModel函数传递的字符串。res的值显示为b'\xd0'(我使用的是ipyt
extern'C'
声明const char*runSmpModel(…)
。python函数原型的编码和运行方式如下:
proto_SMP = c.CFUNCTYPE(c.c_char_p,...)
runSmpModel = proto_SMP(('runSmpModel',smpLib))
res = runSmpModel(...)
这一切都运行得很好,但我无法解码res
变量并获取由CrunSmpModel
函数传递的字符串。res
的值显示为b'\xd0'
(我使用的是ipython3
)。我在网上找到的最佳解决方案--res.decode('utf-8')
给出了错误:
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd0 in position 0: unexpected end of data
runSmpModel
函数的const char*
返回值来自
std::string scenID = SMPLib::SMPModel::runModel(...);
return scenID.c_str();
在runModel内部,它的最终定义如下所示,其中scename
是一个输入字符串:
auto utcBuffId = newChars(500);
sprintf(utcBuffId, "%s_%u", scenName.c_str(), microSeconds); // catenate scenario name & time
uint64_t scenIdhash = (std::hash < std::string>() (utcBuffId)); // hash it
auto hshCode = newChars(100);
sprintf(hshCode, "%032llX", scenIdhash);
scenId = hshCode;
python代码是(与smpLib的定义相同,如上所示):
这将导致解码错误,除非从C函数中的
scenarioID
变量中删除任何字符。所以问题似乎是“Python如何使用ctypes
读取长度超过15个字符的Cchar*
,经过几天的调试和测试,我终于使用@Petesh发布的第二个解决方案实现了这一点。我不明白为什么ctypes
显然将从C传递的char*
值限制为15个字符(+终止=256位?)
基本上,解决方案是向C函数传递一个额外的
char*buff
缓冲区,该缓冲区已使用ctypes.create_string_buffer(32*16)
,以及一个值为32*16的unsigned int buffsize
。然后,在C函数中执行scenarioID.copy(buff,buffsize)
。python原型函数的修改非常明显。一个字节不能突然变为16。您遇到了另一个问题。调用返回一个指向以b'\xd0\x00'
开头的缓冲区的指针。如果你真的需要帮助,你必须提供函数的文档——函数的功能、参数、失败时的行为等等。要求所有这些信息听起来不合理——只需要关于这个返回值的信息。我已经编辑了问题,添加了这些信息。你说得对,我们不需要所有这些信息。我们需要的是一个安全的环境。编写一个等效的、简化的函数,只返回该格式的字符串(几行C),用Python ctypes包装它,并重现您的问题。发布C和Python代码。
extern "C" {
const char* testMeSO()
{
string scenarioID = "abcdefghijklmnop";
return scenarioID.c_str();
}
}
proto_TST = c.CFUNCTYPE(c.c_char_p)
testMeSO = proto_TST(('testMeSO',smpLib))
res = testMeSO()
print("Scenario ID: %s"%res.decode('utf-8'))