나는 python ctypes 모듈을 낯선 사람은 아니지만 이것은 C++, C 및 Python을 모두 하나의 코드로 결합한 첫 번째 시도입니다. 내 문제는 Seg fault when using ctypes with Python and C++과 매우 유사하지만 문제를 같은 방법으로 해결할 수는 없습니다. ctypes/C++ segfault 액세스 멤버 변수
나는 간단한 C++ 파일Header.cpp
라고 있습니다
g++ -c Header.cpp -fPIC -o Header.o
g++ -shared -fPIC -o libHeader.so Header.o
및 test.py
라는 간단한 파이썬 래퍼 :
import ctypes as C
lib = C.CDLL('./libHeader.so')
class Foo(object):
def __init__(self,nbits):
self.nbits = C.c_int(nbits)
self.obj = lib.Foo_new(self.nbits)
def bar(self):
lib.Foo_bar(self.obj)
def main():
f = Foo(32)
f.bar()
if __name__ == "__main__":
main()
을 내가 사용하여 공유 라이브러리에 컴파일
#include <iostream>
class Foo{
public:
int nbits;
Foo(int nb){nbits = nb;}
void bar(){ std::cout << nbits << std::endl; }
};
extern "C" {
Foo *Foo_new(int nbits){ return new Foo(nbits); }
void Foo_bar(Foo *foo){ foo->bar(); }
}
나는 test.py를 호출 할 때 numbe를 가져야한다고 생각한다. r 32가 화면에 인쇄됩니다. 그러나, 내가 얻는 것은 모두 세분화 오류입니다. 스택에서 클래스 인스턴스를 반환하도록 생성자를 변경 한 다음 (예 : new
호출없이) 객체를 전달하면 프로그램이 예상대로 수행됩니다. 또한,의 방법을 변경하여 nbits
멤버를 사용하지 않는 경우, 프로그램에서 오류가 발생하지 않습니다.
저는 C++에 대한 제한된 이해가 있습니다. 그러나 C 및 C++에서이 함수를 예상대로 사용할 수 있지만 Python에서는 사용할 수 없다는 사실은 다소 혼란 스럽습니다. 어떤 도움이라도 대단히 감사하겠습니다.
업데이트 : 아래 의견 중 하나 덕분에 문제가 해결되었습니다. 이 경우 C 함수에 대한 restype 및 argtypes에 대한 명시적인 선언이 필요했습니다.
lib.Foo_new.restype = C.c_void_p;
lib.Foo_new.argtypes = [C.c_int32];
lib.Foo_bar.restype = None;
lib.Foo_bar.argtypes = [C.c_void_p];
저에게 맞습니다. Erratum : Header.cpp를 -fPIC 스위치로 컴파일했다고 가정합니다. – udoprog
여기에서도 작동합니다. segfault의 gdb 백 트레이스를 제공하십시오. –
나를 위해 일한다. Foo에 대한 포인터를 C int로 전달하면 실패 할 수 있습니다. argtypes 및 restype 함수를 지정해보십시오. 'lib.Foo_new.restype = C.c_void_p; lib.Foo_new.argtypes = [C.c_int32]; lib.Foo_bar.restype = None; lib.Foo_bar.argtypes = [C.c_void_p]' – cgohlke