2010-01-25 4 views
3

두 개의 다른 Python 확장 모듈이 있습니다. 그것들을 A와 B라고 부르 자. Module A는 클래스 메소드의 반환 유형으로 Module B 내에서 사용하려는 container라는 저장 클래스 유형을 포함한다.Python C API에서 여러 모듈/유형 사용?

내가 어떻게해야하는지에 대한 문서를 찾을 수없는 것 같습니다. 모든 메소드를 정적으로 선언하지 않았기 때문에이 기사를 대략적으로 모듈/클래스를 작성하기 위해 따라 갔다. 그래서 접근 할 수있다. http://nedbatchelder.com/text/whirlext.html

그럼, 어떻게하면 컨테이너의 인스턴스를 만들 수 있을까요? 모듈 B에서 클래스 메소드의 PyObject * 반환 값으로 다시 전달할 수 있습니까? 컨테이너의 정의는 다음과 같습니다

typedef struct { 
    PyObject_HEAD 

    storageclass* cnt_; 
} container; 

나는 단순히 container_init 내가 컨테이너 클래스에 대한 tp_init로 등록하는 방법입니다 문제가되는 방법 내에서 다음을 수행하려 그러나 따라

pycnt::container* retval; 
pycnt::container_init(retval, NULL, NULL); 
return (PyObject*)retval; 

파이썬 인터프리터에게 내가 메소드를 호출 한 클래스를 돌려 주겠다. (즉, myclassinstance.mymethod()는 myclassinstance를 반환합니다).

분명히 잘못된 방향으로 가고 있습니다. 그러나 나는 올바른 방법이 무엇인지 잘 모릅니다. 어떤 제안? 아무에게도 그것을 줄이기 위해 제안 할 것입니다. SWIG 나 Boost :: Python을 사용하는 것에 관심이 없습니다. 나는 이것을 이미 시도해 보았고 container에 대한 기본 스토리지 클래스는 (SWIG가 그것을 파싱 할조차하지 못해) 훌륭하게 실행되지 않았다. 지금까지 확장 프로그램을 직접 작성하는 것은 꽤 어려움이 있었지만이 문제에 난처합니다.

답변

3

문제는 type->tp_init이 원하는 것을 수행하지 않는다는 것입니다. type->tp_init은 개체가 인스턴스화를 수행하기 위해 할당 된 후에 호출됩니다. 먼저 type->tp_new을 사용하여 객체를 할당 한 다음 해당 객체를 type->tp_init의 첫 번째 인수로 전달해야합니다. 초기화되지 않은 포인터를 tp_init에 전달하면 모든 베팅이 해제됩니다. 하지만 일반적으로 직접 두 함수를 호출하지 않고 대신 객체 유형 자체에 PyObject_Call*() 중 하나를 호출하여 새 인스턴스를 만듭니다. 또는 새로운 인스턴스를 생성하기 위해 일반적인 C 함수를 제공하면 la PyFoo_New()입니다.

즉, 두 개의 확장 모듈 간 상호 통신을 수행하는 일반적인 방법은 Python API를 통해이를 수행하는 것입니다. 모듈 B가 모듈 A를 가져오고 사용하게하려면 모듈 객체를 얻으려면 PyImport_Import()을 호출하고 관심 객체 유형을 가져 오려면 PyObject_GetAttrString()을 호출하고 PyObject_Call*() 중 하나를 호출하면 인스턴스화 할 수 있습니다. 해당 유형에 대한 포인터를 저장하려는 장소는 PyObject *입니다.

+0

모듈을 결합하고 각 유형에 대해 PyFoo_New() 메소드를 작성하면 모든 것이 훌륭하게 작동합니다. 하나의 질문이지만 모듈을 하나에 결합하기 전에 다른 모듈 내부에서 PyContainer_New() 메서드를 사용하고 인터프리터가 컨테이너 객체를 반환한다고보고했지만 그 중 하나를 호출 할 수는 없습니다. 왜 그런가요? 컨테이너 모듈을 가져 왔지만 여전히 운이 없다. –

+0

충분한 분석을하기에는 정보가 충분하지 않지만 첫 번째 모듈의 코드를 두 번, 한 번은 가져 오는 공유 객체로, 다른 모듈의 종속성을 통해 한 번 포함시키는 것이 좋습니다. (정적 또는 동적으로 링크 됨.) 두 번째 어커런스의 PyContainer_New()를 호출하면 초기화되지 않은 모든 데이터 구조가 제공됩니다. –