Reputation: 2075
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
m
but keep it as a variablem
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
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