2014-01-20 1 views
0

PHP에서 사용할 수 있도록 Swig을 사용하여 C 라이브러리를 래핑했습니다. 라이브러리는 unsigned char * 대신 u_char *을 사용합니다. Swig는 u_char를 알지 못하는 구조로 취급합니다.Swig에게 'unsigned char *'로 'u_char *'를 대하는 방법

이 결과는 생성 된 코드가 인수 유형을 확인하는 결과를 낳습니다. 이는 문자를 char * 데이터로 전달할 때 분명히 실패합니다.

어떻게하면 u_char 포인터가 부호없는 char 포인터인지 Swig에게 알릴 수 있습니까? 즉,이 C 함수

int c_library_function(u_char *data, size_t data_size); 

생성 된 코드의 내측이 검사를 가지고

if(SWIG_ConvertPtr(*args[0], (void **) &arg1, SWIGTYPE_p_unsigned_char, 0) < 0) { 
    SWIG_PHP_Error(E_ERROR, "Type error in argument 1 of c_library_function. Expected SWIGTYPE_p_unsigned_char"); 
} 

을 실패 곳인.

%typemap(ctype) u_char "unsigned char"을 Swig 템플릿에 추가하려고 시도했지만 아무런 효과가없는 것으로 보입니다.

한 가지를 명확히하기 위해 편집은의 u_char 확실히 서명 숯불입니다. 또한,

typedef unsigned char __u_char; 

, 단지 유형을 캐스팅 할 수 있도록, C 함수 호출을 래핑하는 함수를 작성 예상대로 작동 : 라이브러리에있는 C 파일은 항목이 bits/types.h을 포함 sys/types.h을 포함하고 있습니다 :

void libraryFunction(u_char *foo) { 
    //Does stuff with foo 
} 

void castLibraryFunction(char *foo) { 
    libraryFunction((u_char *)foo); 
} 

그러나 u_char * 매개 변수가 필요한 모든 함수에 대한 래퍼를 작성하고 싶지는 않습니다.

더욱 분명하게 Swig이 검사하는 유형은 SWIGTYPE_p_unsigned_char입니다. 즉 데이터 유형이 '서명되지 않은 char'이지만 '서명되지 않은 char'포인터가 아니라 사용자 정의 구조의 포인터 인 것으로 이해합니다.

답변

1

Is u_char a standard?에 따르면 u_char는 unsigned char이 아닌 uint8_t (C99)와 동일합니다. 따라서 PHP에서받은 unsigned char 배열을 가지고 있다면 uint8_t (u_char)의 새로운 배열에 문자를 복사하고, lib의 C 함수를 호출하고, 데이터를 수정하면 (u_char * const uchar *가 아님) PHP는 변경 사항을 원래의 배열로 복사해야합니다. PHP가 불변의 문자열을 사용한다면, 문자열을 대신 반환해야 할 것입니다.

SWIG는 위의 작업 중 일부 (예 : % 인라인 및 % 확장 등)를 도와 줄 수 있지만 입력 맵이 필요하지 않습니다.

u_char이 정말로 unsigned char이고 PHP가 char *를 제공하면 원칙은 동일하지만 크기 유형이 char *와 같기 때문에 복사 부분이 필요하지 않습니다. 당신은 %의 인라인을 사용할 수 있습니다 : 당신의 u_char의 *를 기대하고 모든 기능을 위해이 일을하고 싶지 않을 경우

%inline %{ 
    int c_library_function(char* phpString, size_t stringSize) { 
      return c_library_function((u_char*) phpString, stringSize); 
    } 
%} 

, 당신의 유일한 옵션이있는 타입 맵 항목라고 생각합니다.나는 그런

%array_class(unsigned char, char); 

또는

%apply char* {unsigned char*}; 

로, 파일하지만 난이 사용한 적이있다.

+0

확실히 명확한 서명되지 않은 char 데이터입니다. 라이브러리에 대한 테스트 중 하나에서, 내가 호출하려고하는 함수는 파일에서 "char *"데이터를 전달하고, 자동으로 u_char로 캐스팅됩니다. – Danack

+0

'uint8_t'는 아마도'unsigned char'를위한 typedef 일 것입니다. typedef는 단지 새로운 타입이 아닌 기존 타입의 별칭을 생성하기 때문에'uint8_t','unsigned char','u_char'는 아마도 * 같은 타입 * 일 것입니다. (Plain'char'는 부호가 있거나 부호가없는 구별 유형입니다.)'char' 또는'unsigned char'와 같은 데이터를 취급하는 포인터 변환은 원칙적으로 문제가 있지만 일반적으로 작동합니다. –

+0

@KeithThompson and Danack 기술은 여전히 ​​적용되며 복사 부분은 필요하지 않습니다. 편집 됨. – Schollii

관련 문제