deepak
deepak

Reputation: 2075

Wrapping simple c++ example with ctypes; segmentation fault

I extended the example provided in this answer by adding a private member variable, and printing it in the bar() function:

#include <iostream>
class Foo{
    private:
        double m;
    public:
        Foo() { m = 2.344; };
        void bar(){
            std::cout << "Hello, number is " << m << std::endl;
        }
};

extern "C" {
    Foo* Foo_new(){ return new Foo(); }
    void Foo_bar(Foo* foo){ foo->bar(); }
}

The ctypes wrapper was unchanged and is:

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

class Foo(object):
    def __init__(self):
        self.obj = lib.Foo_new()

    def bar(self):
        lib.Foo_bar(self.obj)



f = Foo()
f.bar()

When I run the python code (after having already compiled the C++ code earlier), I am getting a segmentation fault that I have narrowed down to the printing of m in bar().

The seg fault does not happen

  1. in the original code
  2. if i remove printing of m but keep it as a variable
  3. if i substitute m with any fixed number in bar().

I am really puzzled why this should be happening. As this is an experiment to learn ctypes, any help would be appreciated.

Upvotes: 1

Views: 3243

Answers (1)

Eryk Sun
Eryk Sun

Reputation: 34270

If you're using 64-bit Python, you need to define the restype and argtypes. Otherwise ctypes defaults to casting the values to a 32-bit C int.

from ctypes import *

lib = CDLL('./libfoo.so')

lib.Foo_new.argtypes = []
lib.Foo_new.restype = c_void_p

lib.Foo_bar.argtypes = [c_void_p]
lib.Foo_bar.restype = None

Here are source links for 2.7.5, Modules/_ctypes/callproc.c:

For 64-bit Windows a C long is 32-bit, but it's 64-bit on most other 64-bit platforms. By forcing int the result is at least consistent.

Upvotes: 3

Related Questions