加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c – ctypes类成员访问segfaulting

发布时间:2020-12-16 07:01:24 所属栏目:百科 来源:网络整理
导读:我有兴趣在 python中使用c类.看着 Calling C/C++ from python?,我决定尝试ctypes.但是,当我尝试更改类成员的值时,我得到段错误. 这是一个重现我的问题的简单示例: C/C++方面: #include iostreamclass Foo{ private: int mValue; public: void bar(){ std::
我有兴趣在 python中使用c类.看着 Calling C/C++ from python?,我决定尝试ctypes.但是,当我尝试更改类成员的值时,我得到段错误.

这是一个重现我的问题的简单示例:

C/C++方面:

#include <iostream>

class Foo{
    private:
        int mValue;
    public:
        void bar(){
            std::cout << "Hello" << std::endl;
        }
        void setValue(int inValue) {
            mValue = inValue;
            std::cout << "Value is now: " << mValue << std::endl;
        }
        void setValue2() {
            mValue = 2;
            std::cout << "Value is now: " << mValue << std::endl;
        }
};

extern "C" {
    Foo* Foo_new(){ return new Foo(); }
    void Foo_bar(Foo* foo){ foo->bar(); }
    void Foo_setValue(Foo* foo,int v) { foo->setValue(v); }
    void Foo_setValue2(Foo* foo) { foo->setValue2(); }
}

代码在OSX上编译,包括:

g++ -c -fPIC foo.cpp -o foo.o && g++ -shared -Wl -o libfoo.dylib  foo.o

python方面:

from ctypes import *
lib = cdll.LoadLibrary('./libfoo.dylib')

class Foo(object):
    def __init__(self):
        self.obj = lib.Foo_new()
    def bar(self):
        lib.Foo_bar(self.obj)
    def set(self,v):
        lib.Foo_setValue(self.obj,v);
    def set2(self):
        lib.Foo_setValue2(self.obj);

我可以毫无问题地调用bar,但如果我调用set或set2,我会遇到段错误.

f = Foo()
f.bar()  # Ok
f.set(3) # Segfault

显然,我错过了一些东西.

解决方法

使用以下解决了问题:

def __init__(self):
    lib.Foo_new.restype = c_void_p # Needed
    self.obj = lib.Foo_new()

def set(self,v):
    lib.Foo_setValue(c_void_p(self.obj),v) # c_void_p needed

阅读,它似乎是一个64位指针问题.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读