使用ctypes在Python中解码C const char *

德鲁博士

我正在Python 3中使用ctypes(导入为c)执行C ++共享库。该库使用以下命令加载到python中:

smpLib = c.cdll.LoadLibrary(os.getcwd()+os.sep+'libsmpDyn.so')

函数之一具有extern 'C'声明const char* runSmpModel(...)python函数原型的编码和运行方式为:

proto_SMP = c.CFUNCTYPE(c.c_char_p,...)
runSmpModel = proto_SMP(('runSmpModel',smpLib))
res = runSmpModel(...)

所有这些都能很好地工作,但是我无法解码res变量并获得CrunSmpModel函数传递的字符串res(我正在使用ipython3的值显示b'\xd0'我在网上找到的最佳解决方案-res.decode('utf-8')给我错误:

UnicodeDecodeError: 'utf-8' codec can't decode byte 0xd0 in position 0: unexpected end of data

函数const char*返回值runSmpModel来自

std::string scenID = SMPLib::SMPModel::runModel(...);
return scenID.c_str();

在runModel内部,最终定义如下所示,其中scenName是输入字符串:

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;

此特定参数的值res应为0000000000000000BBB00C6CA8B8872E如何解码此字符串?

经过大量的进一步测试后,我已经确定问题出在C函数传递的字符串的长度上。如果字符串的长度最多为15个字符,但长度不超过16个,则没有问题-没有骰子。对于最低工作示例,C代码为:

extern "C" {
  const char* testMeSO()
  {
    string scenarioID = "abcdefghijklmnop";
    return scenarioID.c_str();
  }
}

和python代码是(与smpLib相同的定义,如上所示):

proto_TST = c.CFUNCTYPE(c.c_char_p)
testMeSO = proto_TST(('testMeSO',smpLib))
res = testMeSO()
print("Scenario ID: %s"%res.decode('utf-8'))

除非从scenarioIDC函数中变量中删除了任何字符,否则都会产生解码错误如此看来,问题是“如何阅读的Python一个Cchar*超过15个字符,使用ctypes

德鲁博士

经过几天的调试和测试,我终于使用@Petesh在此SO post上发布的第二个解决方案开始了这项工作我不明白为什么ctypes显然要限制char *从C传递值到15个字符(+终止= 256位?)。

本质上,解决方案是将char * buff已经使用创建的额外缓冲区ctypes.create_string_buffer(32*16)以及unsigned int buffsize值32 * 16传递给C函数然后,在C函数中执行scenarioID.copy(buff,buffsize)python原型函数以明显的方式进行了修改。

本文收集自互联网,转载请注明来源。

如有侵权,请联系 [email protected] 删除。

编辑于
0

我来说两句

0 条评论
登录 后参与评论

相关文章