ctypes-초급


100

ac 라이브러리를 파이썬 클래스로 "래핑"하는 작업이 있습니다. 문서는이 문제에 대해 매우 모호합니다. 고급 파이썬 사용자 만 ctypes를 구현할 것으로 기대하는 것 같습니다. 글쎄요 저는 파이썬 초보자이고 도움이 필요합니다.

단계별로 도움을 받으면 멋질 것입니다.

그래서 내 C 라이브러리가 있습니다. 어떡하죠? 어떤 파일을 어디에 두나요? 라이브러리를 어떻게 가져 옵니까? 파이썬에 "자동 랩"하는 방법이있을 수 있다고 읽었습니다.

(그런데 python.net에서 ctypes 튜토리얼을 수행했지만 작동하지 않습니다. 즉, 나머지 단계를 채울 수 있어야한다고 생각하고 있습니다.

사실 이것은 내가 그들의 코드에서 얻는 오류입니다.

File "importtest.py", line 1
   >>> from ctypes import *
   SyntaxError: invalid syntax

나는 이것에 대한 단계별 도움을 정말로 사용할 수 있습니다! 고마워 ~


10
당신은이 있나요 >>> importtest.py에? 사람들이 >>> 각 줄에있는 코드를 게시 하면 대화 형 쉘에서 실행되고 있음을 나타냅니다. 파일에서 실행하려면 파일 >>> 이 나타날 때마다 (3> 기호 및 공백) 제거하십시오 .
Chinmay Kanchi

4
>>>s를 입력하지 마십시오 . 이들은 대화 형 쉘에 의해 인쇄되며 소스 파일에서 제외되어야합니다.
nmichaels

8
>>>.py 파일에서! 아야! 전에는 본 적이 없습니다!
David Heffernan

3
솔직히, ctypes를 엉망으로 만들기 전에 약간의 파이썬 (적어도 약간)을 배우십시오. 기본 Python을 모른다고 가정하는 ctypes에 대한 자습서 는 절대 찾을 수 없습니다.
Chinmay Kanchi

3
@spentak : 도움을 요청하면 적절한 정보를 제공하세요. 적어도 당신이 말하는 코드의 마지막 버전을 보여주세요. 예를 들어 "라인 3"에는 무엇이 있습니까?
Francesco

답변:


228

여기에 빠르고 더러운 ctypes 튜토리얼이 있습니다.

먼저 C 라이브러리를 작성하십시오. 다음은 간단한 Hello world 예제입니다.

testlib.c

#include <stdio.h>

void myprint(void);

void myprint()
{
    printf("hello world\n");
}

이제 공유 라이브러리로 컴파일하십시오 ( 여기에있는 mac 수정 ).

$ gcc -shared -Wl,-soname,testlib -o testlib.so -fPIC testlib.c

# or... for Mac OS X 
$ gcc -shared -Wl,-install_name,testlib.so -o testlib.so -fPIC testlib.c

그런 다음 ctypes를 사용하여 래퍼를 작성합니다.

testlibwrapper.py

import ctypes

testlib = ctypes.CDLL('/full/path/to/testlib.so')
testlib.myprint()

이제 실행하십시오.

$ python testlibwrapper.py

그리고 당신은 출력을 볼 수 있습니다

Hello world
$

이미 라이브러리를 염두에두고 있다면 튜토리얼의 파이썬이 아닌 부분을 건너 뛸 수 있습니다. ctypes가 라이브러리를 /usr/lib또는 다른 표준 디렉토리 에 넣어 찾을 수 있는지 확인하십시오 . 이렇게하면 래퍼를 작성할 때 전체 경로를 지정할 필요가 없습니다. 이렇게하지 않으려면을 호출 할 때 라이브러리의 전체 경로를 제공 해야합니다ctypes.CDLL() .

더 포괄적 인 튜토리얼이있는 곳은 아니지만이 사이트의 특정 문제에 대한 도움을 요청하면 커뮤니티가 도움을 줄 것이라고 확신합니다.

추신 : 당신이 사용했기 때문에 Linux를 사용하고 있다고 가정합니다 ctypes.CDLL('libc.so.6'). 다른 OS를 사용하는 경우 상황이 약간 (또는 상당히 많이) 변경 될 수 있습니다.


1
@ Chinmay : Windows와 C 대신 유사한 코드를 사용할 수 있습니까? 비주얼 C ++ 예제를 제공해 주시겠습니까? 내 라이브러리를로드 할 수 있지만 .dll 파일에서 내 기능에 액세스 할 수 없습니다. 항상 "기능 'xyz'를 찾을 수 없음"이라고 표시됩니다. 이 문제를 해결하는 방법을 제안 해 주시겠습니까? 건배.
Neophile 2011-09-13

Windows 개발에 대해 잘 모르지만 Windows가 이상한 일을하는 것 같습니다. 아마도 다른 호출 규칙을 사용합니까? 아마도 "extern C"를 사용하여 C ++ 함수를 내보내는 것을 찾을 수 있습니까?
Chinmay Kanchi 2011 년

네, 그렇게했지만 지금까지 운이 없습니다.
Neophile

6
쉬운 주셔서 감사 따를 튜토리얼있는 쇼 CTYPE의 기본 기능
okysabeni

1
신속하고 더러운 항상 최고의 튜토리얼입니다
lurscher

55

Chinmay Kanchi의 대답은 훌륭하지만 C ++ 코드에 변수 / 배열을 전달하고 반환하는 함수의 예를 원했습니다. 다른 사람에게 유용 할 경우를 대비하여 여기에 포함하겠습니다.

정수 전달 및 반환

정수를 취하고 반환 된 값에 1을 더하는 함수에 대한 C ++ 코드,

extern "C" int add_one(int i)
{
    return i+1;
}

파일로 저장 test.cpp하고 필요한 extern "C"를 기록합니다 (C 코드의 경우 제거 할 수 있음). 이것은 Chinmay Kanchi 답변과 유사한 인수로 g ++를 사용하여 컴파일됩니다.

g++ -shared -o testlib.so -fPIC test.cpp

파이썬 코드를 사용 load_library로부터 numpy.ctypeslib파이썬 스크립트와 같은 디렉토리에 공유 라이브러리에 대한 가정의 경로,

import numpy.ctypeslib as ctl
import ctypes

libname = 'testlib.so'
libdir = './'
lib=ctl.load_library(libname, libdir)

py_add_one = lib.add_one
py_add_one.argtypes = [ctypes.c_int]
value = 5
results = py_add_one(value)
print(results)

예상대로 6이 인쇄됩니다.

배열 전달 및 인쇄

C 코드가 배열의 요소를 인쇄하려면 다음과 같이 배열을 전달할 수도 있습니다.

extern "C" void print_array(double* array, int N)
{
    for (int i=0; i<N; i++) 
        cout << i << " " << array[i] << endl;
}

이전과 같이 컴파일되고 동일한 방식으로 가져옵니다. 이 함수를 사용하기위한 추가 Python 코드는 다음과 같습니다.

import numpy as np

py_print_array = lib.print_array
py_print_array.argtypes = [ctl.ndpointer(np.float64, 
                                         flags='aligned, c_contiguous'), 
                           ctypes.c_int]
A = np.array([1.4,2.6,3.0], dtype=np.float64)
py_print_array(A, 3)

여기서 배열,에 대한 첫 번째 인수 print_array는 정렬 된 Numpy 배열에 대한 포인터로 c_contiguous 64 비트 부동 소수점 및 두 번째 인수는 C 코드에 Numpy 배열의 요소 수를 알려주는 정수로 지정합니다. 이것은 다음과 같이 C 코드로 인쇄됩니다.

1.4
2.6
3.0

5
이것은 훌륭한 보충 답변입니다 - 수치가 두 쳤다 답변 :( 수 없습니다
jtlz2

너무 분명한지 확실하지 않지만 코드에 오류가 있습니다. 누락되었습니다 import numpy as np. 그렇지 않으면 np.float64다른 물건 을 찾을 수 없습니다 .
Ben

@Ben, 좋은 자리, 추가됨
Ed Smith

11

첫째 : >>>파이썬 예제에서 볼 수있는 코드는 그것이 파이썬 코드임을 나타내는 방법입니다. 출력에서 Python 코드를 분리하는 데 사용됩니다. 이렇게 :

>>> 4+5
9

여기서 우리는로 시작하는 줄이 >>>파이썬 코드이고 9가 그 결과임을 알 수 있습니다. 이것은 파이썬 인터프리터를 시작하면 정확히 어떻게 보이는지, 이것이 그렇게 된 이유입니다.

파일에 >>>부품을 입력하지 않습니다 .py.

구문 오류를 처리합니다.

둘째, ctypes는 Python 라이브러리를 래핑하는 여러 방법 중 하나 일뿐입니다. 다른 방법으로는 SWIG가 있습니다 .이 방법은 Python 라이브러리를 살펴보고 C API를 노출하는 Python C 확장 모듈을 생성합니다. 또 다른 방법은 Cython 을 사용하는 것 입니다.

그들 모두는 장단점이 있습니다.

SWIG는 C API를 Python에만 노출합니다. 즉, 객체 나 아무것도 얻지 못하므로 별도의 Python 파일을 만들어야합니다. 그러나 "wowza"라는 모듈과 C API를 둘러싼 래퍼 인 "_wowza"라는 SWIG 모듈이있는 것이 일반적입니다. 이것은 일을하는 좋고 쉬운 방법입니다.

Cython은 C-Extension 파일을 생성합니다. 작성하는 모든 Python 코드가 C로 작성된다는 이점이 있으므로 작성하는 객체도 C로 작성되어 성능이 향상 될 수 있습니다. 그러나 C와 인터페이스하는 방법을 배워야하므로 사용 방법을 배우려면 약간의 추가 작업이 필요합니다.

ctypes는 컴파일 할 C 코드가 없다는 이점이 있으므로 다른 사람이 작성한 표준 라이브러리를 래핑하는 데 사용하는 것이 매우 좋으며 Windows 및 OS X 용 바이너리 버전에 이미 존재합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.