deepak deepak -4 years ago 70
Python Question

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.

Answer Source

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.

Recommended from our users: Dynamic Network Monitoring from WhatsUp Gold from IPSwitch. Free Download