尝试在 Python 3 中使用 C++ 类时出错

Posted

技术标签:

【中文标题】尝试在 Python 3 中使用 C++ 类时出错【英文标题】:Error trying to use a C++ class inside Python 3 【发布时间】:2017-12-11 20:42:40 【问题描述】:

我正在尝试在 Python 内部使用我在 C++ 上声明和实现的类。 即使我在 Python 包装器中成功声明了我的类,当我尝试使用该类的函数时,甚至当我尝试创建此类的实例时,我都会得到:

[andre@atlantis mcasta]$ python TimedInputWrapper.py
terminate called after throwing an instance of 'std::bad_alloc'
  what():  std::bad_alloc
Aborted (core dumped)

这是我的 C++ 文件 (input_timeout.cpp):

#include <iostream>
#include <thread>
#include <chrono>
#include <mutex>
#include <condition_variable>
#include <string>

class TimedInput 
    std::condition_variable cv;
    std::string prompt, input_string;
    long int li_time_limit;
    std::chrono::seconds time_limit;
public:
    TimedInput(std::string prompt_str, long int time) : promptprompt_str, li_time_limittime  

    void read_string() 
        std::cin >> input_string;
        cv.notify_one();
    

    std::string return_input() 
        std::cout << "Time limit for input = " << li_time_limit << " seconds!\n" << prompt << "\n";
        std::thread th(&TimedInput::read_string, this);

        std::mutex mtx;
        std::unique_lock<std::mutex> lck(mtx);
        time_limit = (std::chrono::seconds) li_time_limit;

        while ((cv.wait_for(lck, time_limit) != std::cv_status::timeout) and (input_string.empty()))  

        th.detach();
        return input_string;
    
;

extern "C" 
    TimedInput* TimedInput_new(std::string prompt, long int time_limit)  return new TimedInput(prompt, time_limit); 
    void TimedInput_read_string(TimedInput* timed_input)  timed_input->read_string(); 
    std::string TimedInput_return_input(TimedInput* timed_input)  timed_input->return_input(); 

我用这些命令创建了一个共享库:

g++ -c -fPIC -pthread input_timeout.cpp -o input_timeout.o
g++ -shared -Wl,-soname,libTimedInput.so -o libTimedInput.so  input_timeout.o

这是我的 Python Wrapper/test(TimedInputWrapper.py):

import ctypes

lib = ctypes.cdll.LoadLibrary('./libTimedInput.so')


class TimedInput(object):
    def __init__(self, prompt, time_limit):
        self.prompt = prompt
        self.time_limit = time_limit
        self.obj = lib.TimedInput_new(self.prompt, self.time_limit)

    def read_string(self):
        lib.TimedInput_read_string(self.obj)

    def return_input(self):
        lib.TimedInput_return_input(self.obj)

prompt = ctypes.c_wchar_p("What's your name?")
time_limit = ctypes.c_long(10)

TimedInput(prompt, time_limit).return_input()

【问题讨论】:

锁看起来不对,所以在担心 python 之前,我打算尝试在 c++ 中调用这些函数。但是,编译器的代码存在多个问题,所以我什至无法做到。 我从来没有像你的例子那样尝试在 Python 中使用 C++ 方法——我不确定这是否是正确的方法。但是,对于您的目的,boost::pythonpybind11 似乎可以正常工作。 ctypes 不理解 std::stringTimedInput_new 应该取而代之的是 const char* 并且您应该将字符串作为来自 Python 的字节字符串传递。 ctypes 也会有问题,return_input() 返回 std::string 也是如此。 【参考方案1】:

Python ctypes 不适用于 C++ 类型,例如 std::string。但是,ctypes 确实适用于 C 语言类型,例如 const char*

请参阅 Python ctypes 文档中的 Fundamental Data Types。

【讨论】:

以上是关于尝试在 Python 3 中使用 C++ 类时出错的主要内容,如果未能解决你的问题,请参考以下文章

使用 pybind11 包装 C++ 抽象类时出错

C++ 迭代器:实现迭代器类时出错

将 `__str__` 方法添加到 Boost Python C++ 类时的构建问题

在 kotlin REPL 和暂存文件中使用 json 类时出错

c++ 中的嵌入式 python 代码 - 导入 python 库时出错

GreenDao 生成器类在生成模型和 dao 类时出错。