Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/349.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
用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 - Fatal编程技术网

用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
变量并获取由C
runSmpModel
函数传递的字符串。
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个字符的C
char*
,经过几天的调试和测试,我终于使用@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'))