2011-04-07 6 views
4

미안 해요,하지만 난 일반적으로 힘든 시간 현재하는 ctypes 문서를 읽기가 ...ctypes를 통해 참조로 파이썬 문자열을 전달할 수 있습니까?

나는 const char * 포인터를 취하는 C의 기능을 가지고 있고, 나는 그것이 어느 쪽도에 전달되지 수정합니다 알고 경우 문자열을 참조하거나 함수 호출을 넘어서 참조를 유지하지 않으면 실제로 파이썬 문자열의 바이트에 직접 포인터를 전달하는 것이 좋습니다.

ctype이이를 수행 할 수 있습니까? 아니면 일반 지원되지 않습니까? 내가 정말로 create_string_buffer해야하고 그것에 내 문자열을 복사합니까? (파이썬 문자열는 불변이기 때문에, 당연히 생략) 포인터 유형 c_char_p 인스턴스에 대한 새로운 값을 할당

답변

13

는 c_wchar_p 및 c_void_p들은 상기 메모리 블록이 아닌 컨텐츠가 가리키는 메모리 위치를 변경합니다

>>> s = "Hello, World" 
>>> c_s = c_char_p(s) 
>>> print c_s 
c_char_p('Hello, World') 
>>> c_s.value = "Hi, there" 
>>> print c_s 
c_char_p('Hi, there') 
>>> print s     # first string is unchanged 
Hello, World 
>>> 

당신은 조심해야한다 , 그러나, 로는 변경 가능한 메모리에 포인터를 기대 함수에 전달합니다. 에 가변 메모리 블록이 필요한 경우, ctypes에는 create_string_buffer 함수가 있습니다. 은 다양한 방법으로 이들을 만듭니다.

가하는 ctypes 튜토리얼을 말한다 다음 현재 메모리 블록의 내용은 NUL은 문자열을 종료로, 액세스 문자열을 속성을 사용하려는 경우 는, 원시 속성을 액세스하거나 변경할 수 있습니다. 내가 여기서 수집 한 것은 함수가 const char*으로 작동 할 때에 만 파이썬 문자열을 전달하는 것이 유효하다는 것이다. 명심하십시오, 그것은 null 종결을 가지지 않을 것입니다.

어쨌든 create_string_buffer을 사용하는 것이 좋습니다.

+0

감사합니다, 당신은 완전히 정확합니다. 나는 이것을 읽기 전에 막연히 기억합니다. 나는 튜토리얼에 핵심 정보를 넣기 위해 ctypes 문서를 경멸한다. – porgarmingduod

+0

나는 그것에 대해 듣는다. 파이썬 문서는 멋지다. 뭔가를 볼 때가있다. 그런 다음 당신이하고 싶은 일과 관련된 모든 것을 읽어야합니다. 나는 충분히 스트레스를받을 수 없다. 당신이 파스 한 문자열은 null로 끝나지 않을 것이다. 따라서 std :: string 또는 string.h 함수를 사용하지 마십시오.) – bryanegr

+0

ctypes에 전달 된 파이썬 문자열은 * 종료됩니다. c_char_p 타입을 취하는 함수에 파이썬 문자열을 전달하는 것은 유효합니다. –

4

유형 ctypes.c_char_p은 끝이없는 문자열을 나타냅니다. 함수가 const char *을 취하면 파이썬 문자열을 넘겨 줄 수 있고 그것은 null로 끝나는 버전을받을 것이다.

윈도우 예를 들어, DLL :

#include <string.h> 

__declspec(dllexport) char* func(char* a,size_t len,const char* b) 
{ 
    if(strlen(b) * 2 >= len) 
     return NULL; 
    strcpy_s(a,len,b); 
    strcat_s(a,len,b); 
    return a; 
} 

파이썬 :

Python 2.7.1 (r271:86832, Nov 27 2010, 18:30:46) [MSC v.1500 32 bit (Intel)] on win32 
Type "help", "copyright", "credits" or "license" for more information. 
>>> from ctypes import * 
>>> x=CDLL('x') 
>>> x.func.restype=c_char_p 
>>> x.func.argtypes=[c_char_p,c_int,c_char_p] 
>>> s=create_string_buffer(10) 
>>> x.func(s,len(s),'abcd') 
'abcdabcd' 
>>> 
+0

Python docs say ... "이 함수 호출에서 매개 변수로 직접 사용할 수있는 유일한 원시 Python 객체는 정수, longs, 바이트 문자열 및 유니 코드 문자열입니다. ... 바이트 문자열과 유니 코드 문자열이에 대한 포인터로 전달됩니다. 데이터 (char * 또는 wchar_t *)를 포함하는 메모리 블록. " ... [기본 데이터 형식] 바로 앞에 [함수 호출] (http://docs.python.org/2/library/ctypes.html#calling-functions) 섹션 (http : //docs.python .org/2/library/ctypes.html # fundamental-data-types) –

+0

Python C API 함수 [PyString_AsString]에 대한 Python 설명서 (https://docs.python.org/2.7/c-api/string.html? highlight = pystring # c.PyString_AsString) : * string의 내용을 NUL로 종료 한 표현을 반환합니다. 포인터는 문자열의 내부 버퍼를 가리키며 복사되지 않습니다 *. 내부 문자열 버퍼는 널로 끝난다. –

관련 문제