struct a { }
이 정의되어 있습니다. 내 C 함수는 struct a
배열을 참조로 가져온 다음 데이터를 채 웁니다. 따라서 인수는 struct a **
입니다. 필자는 SWIG 인터페이스를 사용하여이 함수를 파이썬에서 호출하려고합니다. 그렇게 할 수있는 방법이 있습니까?포인터 배열을 사용하는 함수 줄 바꾸기
답변
SWIG 및 Python으로이 작업을 수행 할 수 있습니다. 나는 deomstrate 다음 test.h 파일을 설정 한 :
struct a {
int val;
};
static void populate(struct a **list) {
int count = 0;
// Terminate when NULL entry found
while (*list) {
(*list)->val = count++;
++list;
}
}
채우기 기능 목록이 NULL 종료된다고 가정하면, 당신이 설명으로 struct a**
를 받아리스트의 각 요소에 뭔가를한다.
내가 이것을 파이썬에 드러내는 방법은 정수를 취하는 함수, 즉리스트의 크기를 가지고 함수 목록의 결과를 반환하는 함수였다. 내 견해에서 설정 한 "논쟁을 통해 반환".
%typemap(in,numinputs=1) struct a ** (int len=0) {
len = (int)PyInt_AsLong($input);
$1 = malloc(sizeof(struct a*)*(len+1));
$1[len] = NULL;
for (int i = 0; i < len; ++i) {
$1[i] = malloc(sizeof(struct a));
}
}
은 기본적으로는 인수를 취급 :
%module test
%{
#include "test.h"
%}
다음 파이썬 함수에 지정된 크기에 따라 입력 목록을 준비하는 타입 맵을 추가 :
나는 기본 모듈 파일을 설정 정수로 포인터 배열에 메모리를 할당 한 다음 요소 자체가 가리키는 개체에 대해 메모리를 할당합니다. (나는 SWIG/Python이 개별적으로 각각의 항목에 대한 참조 계산을 처리 할 수 있도록 개별적으로 할당했다. 모든 요소에 대해 하나의 블록을 할당하는 것보다 간단하다)
작성된 typemap을 사용하여 나는 또 다른 typemap을 추가했다. 함수를 호출의 결과를 측정하고 PyList로 다시 변환 :
%typemap(argout) struct a ** {
// Push into PyList for return
$result = PyList_New(len$argnum);
for (int i = 0; i < len$argnum; ++i) {
PyObject *element = SWIG_NewPointerObj(SWIG_as_voidptr($1[i]), SWIGTYPE_p_a, SWIG_POINTER_OWN);
PyList_SET_ITEM($result, i, element);
}
}
그것의 NULL 종료 이후 우리가 다시 길이를 계산 만있을 수 있지만 그것은, 우리는 타입 맵에서에서 만든 len
변수의 활용 . 그런 다음 populate
함수에 전달한 struct a
각각에 대해 파이썬 목록의 각 항목에 래핑 된 객체 (SWIG/Python 소유)를 채 웁니다. 유형 이름이 다른 경우 SWIGTYPE_p_a
을 적절하게 SWIGTYPE
으로 변경해야합니다. (이들은 생성 된 래퍼 소스에서 찾을 수 있습니다).
%typemap(freearg) struct a ** {
free($1);
}
과 :
마지막으로 우리는, 우리는 C 측의 목록을 가지고 있던 메모리를 해제 할당해야
%include "test.h"
나는 이것을 컴파일 : 다음
swig -python -Wall test.i gcc -Wall -Wextra test_wrap.c -I/usr/include/python2.6 -o _test.so -std=c99 -shared
및 확인하려면 다음 파이썬을 실행 :
개import test
r=test.populate(100)
print r[0].val
여러 지점이 예에서 참고 : 오류 검사가 없습니다
- 가, 나쁜 일을 할 것입니다 예를
test.populate("Hello world")
를 들어,PyList_New
이 실패 할 수 있습니다 우리가 개별 요소를 해제 할 필요가 실패하는 경우, - 메모리 소유권 의미가 다르면
SWIG_POINTER_OWN
을 적절하게 변경해야합니다. - 파이썬 interfa에서 목록의 크기를 지정하지 않으려면 ce (예 : 그것은 다른 것으로 알려져 있거나 고정되어 있습니다)
numinputs=1
을 0으로 변경하고 in typmap에 따라len
을 설정할 수 있습니다. - 함수가 NULL 종료 목록을 사용하는 대신 길이와 길이를 지정하는 목록을 사용하는 경우이를 multi-argument typemap으로 확장 할 수 있습니다.
/컴파일이 예제를 실행하는 데 필요한 모든 코드이 대답에 포함되어 있지만 하나 개의 편리한 타르 그것을 원한다면 또한 on my site을 넣었습니다. 비록 그 링크가 깨져 야하더라도 대답은 여전히 작동합니다.
- 1. 함수 포인터 배열을 C
- 2. 문자열에 줄 바꾸기 줄 바꾸기
- 3. C++ 함수 포인터 이름없는 함수를 사용하는 배열
- 4. 포인터 배열을 사용하는 데 문제가 있습니까?
- 5. UNIX에서 줄 바꾸기 문자 바꾸기
- 6. C에서 함수 포인터 배열
- 7. 함수 포인터
- 8. 함수 포인터
- 9. 함수 포인터?
- 10. 함수 포인터
- 11. 문자 선택 및 줄 바꾸기
- 12. 배열 포인터 함수
- 13. 함수 쿼리 바꾸기
- 14. C# 함수 포인터
- 15. C++ 함수 포인터 구문
- 16. 함수 포인터 __attribute __ ((const)) 함수?
- 17. 함수 포인터 및 가상 함수
- 18. 함수 포인터 및 일반 함수
- 19. 배열을 사용한 포인터 산술
- 20. QVariant.toXXX 함수의 함수 포인터
- 21. NULL 함수 포인터, 함수는
- 22. 다형 멤버 함수 포인터
- 23. 연관 배열을 사용하는 PHP 카운트 함수
- 24. char 배열을 매개 변수로 사용하는 함수
- 25. const 대 포인터 포인터 (함수 용)
- 26. 널 포인터 예외이 줄
- 27. CSV 파일에서 PHP를 사용하여 줄 바꾸기 또는 줄 바꾸기
- 28. jQuery가 배열을 찾아서 바꾸기
- 29. 개체의 함수 포인터
- 30. 함수 포인터 및 상속
답해 주셔서 감사합니다. 며칠 전이 질문/답변을 찾았 으면 좋겠습니다. 나는 비슷한 것을 개발해야만했고 당신과 거의 같은 해결책을 찾았습니다. 대부분의 기술 문제가 이미 해결 된 또 다른 교훈은 ... –