2014-11-21 1 views
0

TL; DR 파이썬의 ctypes 문서에 설명 된 _as_parameter_from_param 메커니즘은 우리의 코드 또는와 OS X의 문제에서 제대로 작동하지 않는 것 ctypes?문제에 파이썬하는 ctypes '_as_parameter_'와 'from_param'와 OS X


작은 컨텍스트 GenomeTools library은 광범위한 C의 API뿐만 아니라 ctypes 구현 파이썬 바인딩의 작은 세트를 포함

. 나는 C API를 꽤 많이 사용하지만 프로젝트의 파이썬 코드를 사용하고 이에 관심이있다. C 코드는 src/이고 파이썬 바인딩은 gtpython/에 구현되어 있습니다.

나는 물건을 테스트하기 위해 더미 스크립트를 작성했습니다.

from gt import * 
print "DEBUG a" 
ingff3 = GFF3InStream("testdata/Scaffold_102.gff3") 
print "DEBUG b" 
outgff3 = GFF3OutStream(ingff3) 
print "DEBUG c" 
outgff3.pull() 
print "DEBUG d" 

문제 라이브러리의 특정 세부 사항을 무시

GFF3InStreamGFF3OutStream 클래스는 C 오브젝트 유형에 대한 파이썬 래퍼입니다. GFF3OutStream 생성자는 C 라이브러리에서 gt_gff3_out_stream_new 생성자를 호출합니다. 해당 C 함수의 첫 번째 인수는 C 개체에 대한 포인터가 될 것으로 예상됩니다. 함수를 호출하는 Python 코드는 Python 객체를 매개 변수로 제공하지만 객체에 _as_parameter_ 속성 집합이 있고 from_param 메서드가 정의되어 있으므로 C 코드에 전달 된 값은 실제로 Python 객체가 캡슐화 한 포인터이며 포인터는 아닙니다. 파이썬 객체 자체.

적어도 아이디어는 Linux에서 작동하는 방식입니다. 하지만 Mac OS X에서는 이러한 메커니즘이 작동하지 않는 것으로 보아 모든 종류의 segfault가 발생합니다. 내가 명시 적으로이에서 생성자 ...

class GFF3OutStream(GenomeStream): 
    def __init__(self, genome_stream): 
     self.gs = gtlib.gt_gff3_out_stream_new(genome_stream, None) 
     self._as_parameter_ = self.gs 

...

class GFF3OutStream(GenomeStream): 
    def __init__(self, genome_stream): 
     self.gs = gtlib.gt_gff3_out_stream_new(genome_stream.gs, None) 
     self._as_parameter_ = self.gs 

을 변경 한 경우에만 ... 나는 OS에 내 작은 더미 스크립트에 대한 올바른 동작을 관찰 할 X.

_as_parameter_from_param 메커니즘이 실제로 Mac OS X에서 사용 가능하지 않습니까? 이 문제는 Python의 ctypes에서 알려진 문제입니까? 아니면 GenomeTools 코드에 문제가 있습니까?

+0

@eryksun 감사합니다. 의견을 답변으로 추가하려면 동의하겠습니다. –

답변

1

은 포인터 값을 정수로 반환합니다. 정수 인수의 기본 변환은 C int이며 64 비트 포인터 값을 자릅니다.

이 문제를 해결하는 데는 최소한 두 가지 방법이 있습니다. 정수 결과를 c_void_p에 랩핑하십시오. getfunc를 호출 건너 뜁니다 c_void_p의 서브 클래스에

class GFF3OutStream(GenomeStream): 
    def __init__(self, genome_stream): 
     self.gs = c_void_p(gtlib.gt_gff3_out_stream_new(genome_stream, None)) 
     self._as_parameter_ = self.gs 

또는 설정 restype.

class my_void_p(c_void_p): 
    pass 

gtlib.gt_gff3_out_stream_new.restype = my_void_p 

class GFF3OutStream(GenomeStream): 
    def __init__(self, genome_stream): 
     self.gs = gtlib.gt_gff3_out_stream_new(genome_stream, None) 
     self._as_parameter_ = self.gs # my_void_p instance 

2.7.8하는 ctypes 소스 링크 : 응답에 대한