【问题标题】:C++ function in python return number instead of stringpython中的C++函数返回数字而不是字符串
【发布时间】:2020-06-12 07:32:24
【问题描述】:

创建字符串的C++:

#include <iostream>
#include <string>

using namespace std;

extern "C" {
    string getchars() {
        string output = "";
        char letters[4] = { 'A', 'G', 'T', 'C' };
        for (int i = 0; i < 10000000; i++) {
            output += letters[rand() % 4];
        }
        return output.c_str();
    }

}

应该返回用 C++ 生成的字符串的 Python 代码:

from ctypes import cdll
lib = cdll.LoadLibrary('mylib.so')
print(lib.getchars())

它返回不同的数字,如 18806352,我应该怎么做才能返回正常的字符串?在 C++ 中这个函数很好用

【问题讨论】:

  • string getchars 应该是 char *getchars,因为这是 c_str() 返回的内容。
  • @Barmar 这将返回一个指向本地的指针。
  • c_str()返回的字符串在std::string被销毁后失效。由于函数返回时output被销毁,所以不能返回output.c_str()
  • 我认为您需要分配一个动态 C 字符串并将output.c_str() 复制到其中,然后返回该指针。
  • @Barmar 我不知道该怎么做,如果你写一点代码我会很感激我怎么做以及为什么

标签: python c++


【解决方案1】:

看看这个讨论。这个问题似乎与 How to return char ** from C++ and fill it in a list in Python using ctypes?

看来您需要在 cdll 中指定函数的返回类型。 所以需要在调用方法之前定义结果类型。

我认为这应该可行。否则,请仔细查看: https://docs.python.org/2/library/ctypes.html

[编辑]

  • 文件test.cpp的C++实现(@Barmar的实现):
#include <iostream>
#include <string>
#include <cstring>

using namespace std;

extern "C" char * getchars() {
    string output = "";
    char letters[4] = { 'A', 'G', 'T', 'C' };
    for (int i = 0; i < 10000000; i++) {
        output += letters[rand() % 4];
    }
    char *return_string = new char[output.length() + 1];
    strcpy(return_string, output.c_str());
    return return_string;
}
  • 编译:
g++ -std=c++11 -Wall -Wextra -pedantic -c -fPIC test.cpp -o test.o
g++ -shared test.o -o test.so
  • Python 文件test.py:
from ctypes import cdll, c_char_p
lib = cdll.LoadLibrary('./test.so')
lib.getchars.restype = c_char_p
result = lib.getchars()
print(result)

Python 版本 3.7.4

这应该可行。

【讨论】:

  • 现在我的 lib.getchars()(在 print(...) 之后)打印出我的 &lt;__main__.LP_c_char_p object at 0x00FD2760&gt;,我怎样才能获得价值?
  • 尝试使用 lib.getchars().value
  • lib.getchars().valuelib.getchars().values 不起作用
  • 因为这是一个python对象,它有一个类型和一个值。
  • 请注意,您可能需要通过 malloc 或其他方式分配数据。因为否则即使您最后返回 .c_str() ,字符串对象也已经被销毁。所以你需要把这些数据分配给python,然后在python中释放。
【解决方案2】:

您需要返回一个 C 字符串,而不是 C++ std::string。您需要制作c_str() 的动态副本,以便它的生命周期超过创建它的函数。

extern "C" {
    char * getchars() {
        string output = "";
        char letters[4] = { 'A', 'G', 'T', 'C' };
        for (int i = 0; i < 10000000; i++) {
            output += letters[rand() % 4];
        }
        char *return_string = new char[output.length() + 1];
        strcpy(return_string, output.c_str());
        return return_string;
    }
}

【讨论】:

  • 'strdup' was not declared in this scope
  • 这是两行可以模拟的琐碎代码,我将其添加到答案中。
  • 做了你写的,包括#include &lt;string.h&gt; #include &lt;stdlib.h&gt;,创建了.so对象,但在python中仍然返回数字..你自己试过吗?也许它会在它对你有用的情况下有意义,或者我错过了……
  • @WhoAmI 我想python仍然会打印指针的值而不是字符串
  • 我假设 ctypes 会对 Python 字符串进行适当的转换。
猜你喜欢
  • 2013-05-16
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-04-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多