Python ctypes字符指针和字符串长度问题

Python ctypes character pointer and string length issues

本文关键字:问题 字符串 ctypes 字符 指针 Python      更新时间:2023-10-16

问题

我正在尝试编写一个外部库从python调用,并希望使用ctypes在python和c++之间传递信息。为此,我在c++中定义了一个名为msg的全局变量,并让我的c++代码向这个全局变量写入消息。这样一来,Python就可以在需要时读取消息。然而,我似乎遇到了这条消息长度的限制。

下面是重现这个问题的代码原型。

#include <iostream>
#include <sstream>
std::ostringstream msg;
void internal(){
    msg << " message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message  message ";
}
extern "C"{
    const char* external(){
        internal();
        return msg.str().c_str();
    }
}

msg现在是一个很长的字符串。我将其保存在一个名为test.cpp的文件中,并将其编译为一个共享库:

g++ -c -fPIC test.cpp -o test.o
g++ -shared -Wl,-soname,test.so -o test.so test.o

我现在打开一个python解释器,并执行以下操作

import ctypes
test = ctypes.cdll.LoadLibrary('test.so')
test.external.restype = ctypes.c_char_p
test.external()

输出是'',而不是我上面构造的超长字符串。

我想python能从c++程序中接受的消息长度有某种上限。然而,在我所拥有的用例中,消息的长度可能是任意的。我如何确保能够将消息读取到python程序中?

如果我用一个非常短的字符串替换长字符串,例如

msg << " message ";

则一切正常,python解释器输出message

系统信息Python解释器

Python 2.7.6 (default, Mar 22 2014, 22:59:56) 
[GCC 4.8.2] on linux2

g++编译器
g++ (Ubuntu 4.8.2-19ubuntu1) 4.8.2

好吧,答案太明显了,我很尴尬,我一开始没有看到它。str()方法正在创建一个临时字符串,在internal()方法结束时该字符串超出作用域后,其指针无效。

下面的代码可以工作:

#include <iostream>
#include <sstream>
std::ostringstream msg;
std::string s;
void internal(){
    for(int i = 0; i < 1000; i++) {
      msg << " message ";
    }
    s = msg.str();
}
extern "C"{
    const char* external(){
        internal();
        return s.c_str();
    }
}