gpt4 book ai didi

python - CTYPES 和 PYTHON3 : Can't return long string

转载 作者:太空宇宙 更新时间:2023-11-04 16:05:54 25 4
gpt4 key购买 nike

我有一个 C++ 代码,我为其创建了一个 python.ctypes 包装器。它工作得很好,除非返回的字符串很长。 C代码示例:

extern "C" {

const char * hallo(char * nome)
{
string str(nome);
str = "hallo " + str;

for(int i=0; i<100; i++)
str += " new content";

return str.c_str();
}

我的 python 代码是:

self.lib = ctypes.CDLL(LIB_PATH)
self.lib.hallo.restype = ctypes.c_char_p
self.lib.hallo.argtypes =[ctypes.c_char_p]
j = self.lib.hallo('my name'.encode())
print('INIT: ' + j.decode())

字符串大小是动态的(实际上,它将是一个 json 字符串)。处理这种情况的最佳方法是什么?

非常感谢。

最佳答案

这里的问题是,当您返回 str.c_str() 时,您返回的是指向堆栈分配内存的指针,该内存在从 C++ 代码返回时被覆盖。

可能的解决方法是使用 static string str 例如:

#include <string>
#include <sstream>

extern "C" {

const char * hallo(char * nome)
{
static std::string str;
std::stringstream stream;
stream << "hallo " << nome;

for(int i=0; i<100; i++)
stream << " new content";

str = stream.str();
return str.c_str();
}

}

虽然这会阻止您从多个线程调用例程。

如果你想从多个地方调用它,你可能应该带一个指向内存的参数指针,并传入一个从 ctypes.create_string_buffer 创建的指针缓冲区(希望它有在这种情况下尺寸合适)。

例如:

#include <string>
#include <sstream>

extern "C" {

const char * hallo(char * nome, char *writebuffer, unsigned int buffersize)
{
std::string str(nome);
str = "hallo " + str;

for(int i=0; i<100; i++)
str += " new content";

if (str.size() < buffersize) {
str.copy(writebuffer, buffersize);
return writebuffer;
} else {
return 0;
}
}

}

然后是一些使用这个库的示例 python 代码;传入 128k 缓冲区(python 3 更新):

import ctypes

lib = ctypes.CDLL(LIB_PATH)
lib.hallo.restype = ctypes.c_char_p
lib.hallo.argtypes =[ctypes.c_char_p, ctypes.c_char_p, ctypes.c_uint]
allocation = ctypes.create_string_buffer(128 * 1024)
j = lib.hallo('my name'.encode(), allocation, 128 * 1024)
if j is not None:
print('INIT: ' + j.decode("UTF-8"))
else:
print("Buffer was too small")

关于python - CTYPES 和 PYTHON3 : Can't return long string,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35584002/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com