社区所有版块导航
Python
python开源   Django   Python   DjangoApp   pycharm  
DATA
docker   Elasticsearch  
aigc
aigc   chatgpt  
WEB开发
linux   MongoDB   Redis   DATABASE   NGINX   其他Web框架   web工具   zookeeper   tornado   NoSql   Bootstrap   js   peewee   Git   bottle   IE   MQ   Jquery  
机器学习
机器学习算法  
Python88.com
反馈   公告   社区推广  
产品
短视频  
印度
印度  
Py学习  »  Python

当将Python元组传递到C++类型的C++函数时,分割错误11

apepkuss • 5 年前 • 1496 次点击  

我试图用Python cType调用Python代码中的一些C++函数。我有两个代码文件:一个是core-lib.cpp,它定义了一个类和一个成员方法;另一个是demo.py,它实例化了类并调用了成员方法。

核心方案 定义如下。

#include <iostream>
#include <tuple>

using namespace std;

class A {
    private:
        string _name;
        tuple<int, int> _size; 

    public:
        A() {
            this->_name = "";
            this->_size = make_tuple(1, 1);
            cout << "Init values of _size: " << get<0>(this->_size) << ", " << get<1>(this->_size) << endl;
        }

        void set_size(int* size) {
            int a = *size;
            int b = *(size+1);

            this->_size = make_tuple(a, b);
            cout << "New values of _size: " << get<0>(this->_size) << ", " << get<1>(this->_size) << endl;
        }
};

// bridge C++ to C
extern "C" {
    A* create_A() {
        return new A();
    }

    void set_size(A* a, int* size) {
        a->set_size(size);
    }
}

演示.py 定义如下。

from ctypes import *
import os

# load C++ lib
core_lib = cdll.LoadLibrary(os.path.abspath('test/stackoverflow/core_lib.so'))

class A(object):
    def __init__(self):
        self.a = core_lib.create_A()

    def set_size(self, size):
        core_lib.set_size(self.a, size)

if __name__ == "__main__":
    asize = (3, 3)
    size = (c_int * 2)(*asize)
    a = A()
    a.set_size(size)

为了重现这个问题,我在这里列出了我的步骤:

  1. 编译core-lib.cpp: G+ + CIEE.LIP.CPP-FPIC-共享STD=C++ 11 -O CORE
  2. 运行python脚本: python演示.py

python版本是2.7.15,运行在macos mojave上。

根据我的调查,这个问题是由core-lib.cpp中的代码行引起的:

this->_size = make_tuple(a, b)

我试图在谷歌上搜索这个问题,但没有找到答案。我希望任何有助于理解这个问题以及如何解决它的评论。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/39751
 
1496 次点击  
文章 [ 1 ]  |  最新文章 5 年前
Mark Tolonen
Reply   •   1 楼
Mark Tolonen    6 年前

定义 .argtypes .restype 为了你的职责。默认类型为 c_int (32位)并且您可能正在使用指针为64位的操作系统,截断 A* 返回值。

core_lib.create_A.argtypes = None
core_lib.create_A.restype = c_void_p
core_lib.set_size.argtypes = [c_void_p,POINTER(c_int)]
core_lib.set_size.restype = None

c_void_p 对于不透明指针就足够了。通过声明指向类的指针,并将大小指针声明为包含两个int的数组,可以获得更好的类型检查:

class A(Structure):
    pass

core_lib.create_A.argtypes = None
core_lib.create_A.restype = POINTER(A)
core_lib.set_size.argtypes = POINTER(A),POINTER(c_int * 2)
core_lib.set_size.restype = None

如果你有选择,我建议你定义 set_size 作为 void set_size(A* a, int x, int y) 所以你可以打电话给 a.set_size(3,3) 直接而不是创建 (c_int * 2)(3,3) 通过。