이것은 Ubuntu Online, Fedora Online, Windows 온라인 에뮬레이터 또는 MAC OS 온라인 에뮬레이터와 같은 여러 무료 온라인 워크스테이션 중 하나를 사용하여 OnWorks 무료 호스팅 제공업체에서 실행할 수 있는 명령 perlxstypemap입니다.
프로그램:
이름
perlxstypemap - Perl XS C/Perl 유형 매핑
기술
두 언어 간의 인터페이스에 대해 더 많이 생각할수록 더 많이 깨닫게 될 것입니다.
프로그래머 노력의 대부분은 데이터 구조 간의 변환에 들어가야 합니다.
관련된 언어 중 하나에 고유합니다. 이것은 다음과 같은 다른 문제보다 우선합니다.
문제 공간이 훨씬 더 크기 때문에 호출 규칙이 다릅니다. 있다
함수를 구현하는 방법보다 데이터를 메모리에 밀어 넣는 방법이 더 많습니다.
요구.
이에 대한 솔루션을 위한 Perl XS의 시도는 typemap의 개념입니다. 추상적인 수준에서,
Perl XS typemap은 특정 Perl 데이터를 변환하는 방법에 불과합니다.
구조를 특정 C 데이터 구조로 또는 그 반대의 경우도 마찬가지입니다. C 유형이있을 수 있으므로
동일한 논리, XS로 변환을 보증할 만큼 서로 충분히 유사합니다.
typemap은 고유 식별자로 표시되며, 이후에는 이를 XS 유형 이번에
문서. 그런 다음 XS 컴파일러에 여러 C 유형이 매핑되도록 알릴 수 있습니다.
같은 XS 타입맵.
XS 코드에서 C 유형으로 인수를 정의하거나 "CODE:"를 사용할 때
XSUB의 C 반환 유형과 함께 "OUTPUT:" 섹션이 표시됩니다.
이것을 쉽게 해주는 typemapping 메커니즘.
해부 of a 타입맵
보다 실용적인 용어로 typemap은 다음에서 사용하는 코드 조각 모음입니다.
전에, xsubpp 컴파일러는 C 함수 매개변수와 값을 Perl 값에 매핑합니다. 타입맵
파일은 "TYPEMAP", "INPUT" 및 "OUTPUT"이라는 레이블이 붙은 세 개의 섹션으로 구성될 수 있습니다. 안
레이블이 지정되지 않은 초기 섹션은 "TYPEMAP" 섹션으로 간주됩니다. INPUT 섹션은
컴파일러는 Perl 값을 특정 C 유형의 변수로 변환하는 방법을 설명합니다. 출력
섹션은 특정 C 유형의 값을 값으로 변환하는 방법을 컴파일러에 알려줍니다.
Perl은 이해할 수 있습니다. TYPEMAP 섹션은 INPUT 및 OUTPUT 중 어느 것을 컴파일러에 알려줍니다.
코드 조각은 주어진 C 유형을 Perl 값에 매핑하는 데 사용해야 합니다. 섹션 레이블
"TYPEMAP", "INPUT" 또는 "OUTPUT"은 한 줄의 첫 번째 열에서 단독으로 시작해야 합니다.
그리고 대문자여야 합니다.
섹션의 각 유형은 임의의 횟수만큼 나타날 수 있으며 나타날 필요는 없습니다.
조금도. 예를 들어, typemap은 일반적으로 "INPUT" 및 "OUTPUT" 섹션이 부족할 수 있습니다.
추가 C 유형을 T_PTROBJ와 같은 핵심 XS 유형과 연결하기만 하면 됩니다. 라인
해시 "#"으로 시작하는 것은 주석으로 간주되고 "TYPEMAP" 섹션에서 무시되지만
"INPUT" 및 "OUTPUT"에서 중요한 것으로 간주됩니다. 빈 줄은 일반적으로 무시됩니다.
전통적으로 typemap은 별도의 파일에 작성해야 했습니다.
CPAN 배포판의 "typemap". ExtUtils::ParseXS(XS 컴파일러) 버전 3.12 사용
perl 5.16과 함께 제공되는 더 나은 버전에서는 typemap을 XS 코드에 직접 포함할 수도 있습니다.
구문과 같은 HERE-doc 사용:
유형 지도: <
...
여기를 클릭하십시오.
여기서 "HERE"는 일반 Perl HERE 문서와 같은 다른 식별자로 대체될 수 있습니다. 모두
typemap 텍스트 형식에 대한 아래 세부 정보는 유효합니다.
"TYPEMAP" 섹션은 다음과 같이 한 줄에 한 쌍의 C 유형과 XS 유형을 포함해야 합니다.
핵심 typemap 파일의 예:
타입맵
# char*의 모든 변형은 T_PV typemap에 의해 처리됩니다.
문자 * T_PV
상수 문자 * T_PV
서명되지 않은 문자 * T_PV
...
"INPUT" 및 "OUTPUT" 섹션은 동일한 형식, 즉 들여쓰기되지 않은 각 행을 갖습니다.
각각 새로운 내부 또는 출력 맵을 시작합니다. 새 입력 또는 출력 맵은 다음으로 시작해야 합니다.
자체적으로 라인에 매핑할 XS 유형의 이름, 그 뒤에 이를 구현하는 코드
다음 줄에 들여쓰기됩니다. 예시:
입력
T_PV
$var = ($type)SvPV_nolen($arg)
T_PTR
$var = INT2PTR($유형,SvIV($인수))
Perlish처럼 보이는 변수의 의미에 대해서는 잠시 후에 알아보겠습니다.
마지막으로 다음은 "char *"의 C 문자열을 매핑하기 위한 전체 typemap 파일의 예입니다.
Perl 스칼라/문자열에 입력:
타입맵
문자 * T_PV
입력
T_PV
$var = ($type)SvPV_nolen($arg)
출력
T_PV
sv_setpv((SV*)$arg, $var);
다음은 더 복잡한 예입니다. "struct netconfig"가
"Net::Config" 클래스에 축복을 받았습니다. 이를 수행하는 한 가지 방법은 밑줄(_)을 사용하여
다음과 같이 별도의 패키지 이름:
typedef 구조체 netconfig * Net_Config;
그런 다음 밑줄을 이중 콜론으로 매핑하는 typemap 항목 "T_PTOBJ_SPECIAL"을 제공합니다.
(::) 그리고 "Net_Config"를 해당 유형으로 선언합니다.
타입맵
Net_Config T_PTOBJ_SPECIAL
입력
T_PTOBJ_SPECIAL
if (sv_derived_from($arg, \"${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\")){
IV tmp = SvIV((SV*)SvRV($arg));
$var = INT2PTR($유형, tmp);
}
그렇지 않으면
croak(\"$var는 ${(my $ntt=$ntype)=~s/_/::/g;\$ntt}\") 유형이 아닙니다.
출력
T_PTOBJ_SPECIAL
sv_setref_pv($arg, \"${(내 $ntt=$ntype)=~s/_/::/g;\$ntt}\",
(무효*)$var);
INPUT 및 OUTPUT 섹션은 이중 콜론을 밑줄로 즉시 대체합니다.
원하는 효과. 이 예는
typemap 시설.
"INT2PTR" 매크로(perl.h에 정의됨)는 주어진 유형의 포인터에 정수를 캐스트합니다.
가능한 다른 크기의 정수와 포인터를 처리합니다. 도 있다
"PTR2IV", "PTR2UV", "PTR2NV" 매크로는 OUTPUT에서 유용할 수 있는 다른 방식으로 매핑합니다.
섹션을 참조하십시오.
The 직위별 of 전에, 타입맵 입양 부모로서의 귀하의 적합성을 결정하기 위해 미국 이민국에 in 너의 콘텐츠 배급
기본 typemap은 라이브러리/ExtUtils Perl 소스의 디렉토리에는 많은 유용한
Perl 확장에서 사용할 수 있는 유형입니다. 일부 확장은 추가 typemap을 정의합니다.
그들은 자신의 디렉토리에 보관합니다. 이러한 추가 typemap은 INPUT 및
OUTPUT은 기본 typemap의 맵입니다. 그만큼 xsubpp 컴파일러는 확장 자체를 허용합니다.
typemap을 사용하여 기본 typemap에 있는 매핑을 재정의합니다. 사용하는 대신
추가 타입맵 파일, typemap은 heredoc과 같은 XS에 그대로 포함될 수 있습니다.
통사론. "TYPEMAP:" XS 키워드에 대한 설명서를 참조하십시오.
CPAN 배포의 경우 perl 코어에 의해 정의된 XS 유형이 다음과 같다고 가정할 수 있습니다.
이미 사용 가능합니다. 또한 핵심 typemap에는 많은 수에 대한 기본 XS 유형이 있습니다.
C 유형의. 예를 들어 XSUB에서 단순히 "char *"를 반환하면 핵심 typemap이
T_PV XS 유형과 연결된 이 C 유형이 있습니다. 즉, C 문자열이
에서 반환될 새 스칼라의 PV(포인터 값) 슬롯에 복사됩니다.
XSUB에서 Perl로.
XS를 사용하여 CPAN 배포판을 개발하는 경우 다음이라는 고유한 파일을 추가할 수 있습니다.
타입맵 배포에. 그 파일은 다음과 같은 유형을 매핑하는 typemap을 포함할 수 있습니다.
코드에 따라 다르거나 공통 C에 대한 핵심 typemap 파일의 매핑을 재정의합니다.
유형.
공유 타입맵 사이에 CPAN 배포판
ExtUtils::ParseXS 버전 3.13_01(perl 5.16 이상과 함께 제공됨)부터 시작합니다.
여러 CPAN 배포판 간에 typemap 코드를 공유하기 쉽습니다. 일반적인 아이디어는
특정 API를 제공하고 종속 모듈이 선언하도록 하는 모듈로 공유하려면
빌드 시간 요구 사항으로 typemap을 XS로 가져옵니다. 그러한 예
CPAN의 typemap-sharing 모듈은 "ExtUtils::Typemaps::Basic"입니다. 그것을 얻기 위한 두 단계
코드에서 사용할 수 있는 모듈의 typemap:
· "Makefile.PL"에서 "ExtUtils::Typemaps::Basic"을 빌드 타임 종속성으로 선언합니다(사용
"BUILD_REQUIRES") 또는 "Build.PL"에서("build_requires" 사용).
· XS 파일의 XS 섹션에 다음 줄을 포함합니다. (줄바꿈하지 않음)
INCLUDE_COMMAND: $^X -MExtUtils::Typemaps::Cmd
-e "embedable_typemap(q{기본}) 인쇄"
쓰기 타입맵 항목
각 INPUT 또는 OUTPUT typemap 항목은 평가될 큰따옴표로 묶인 Perl 문자열입니다.
특정 변수가 있는 경우 특정 C 유형을 매핑하기 위한 최종 C 코드를 가져옵니다.
이는 다음과 같은 구성을 사용하여 Typemap(C) 코드에 Perl 코드를 포함할 수 있음을 의미합니다.
"${ 여기에서 스칼라 참조로 평가되는 펄 코드 }". 일반적인 사용 사례는 다음을 생성하는 것입니다.
ALIAS XS 기능을 사용하는 경우에도 실제 기능 이름을 참조하는 오류 메시지:
${ $별칭 ? \q[GvNAME(CvGV(cv))] : \qq[\"$pname\"] }
많은 typemap 예제는 perl에서 찾을 수 있는 핵심 typemap 파일을 참조하십시오.
소스 트리 라이브러리/ExtUtils/typemap.
typemap에 삽입할 수 있는 Perl 변수는 다음과 같습니다.
· $var - 입력 또는 출력 변수의 이름, 예. 반환 값에 대한 RETVAL.
· $ type - 매개변수의 원시 C 유형, ":"는 "_"로 대체됩니다. 예를 들어 유형의 경우
"Foo::Bar"의 $ type "Foo__Bar"입니다.
· $n유형 - "*"가 있는 제공된 유형은 "Ptr"로 대체되었습니다. 예를 들어 "Foo*" 유형의 경우
$n유형 "FooPtr"입니다.
· $인수 - 매개변수가 입력되거나 출력되는 스택 항목, 예를 들어 ST(0)
· $아르고프 - 인수의 인수 스택 오프셋. 즉. 첫 번째 인수의 경우 0,
등
· $pname - "PACKAGE" 이름을 포함한 XSUB의 전체 이름
"PREFIX"가 제거되었습니다. 이것은 비 ALIAS 이름입니다.
· $패키지 - 가장 최근의 "PACKAGE" 키워드로 지정된 패키지.
· $별칭 - 현재 XSUB에 "ALIAS"로 선언된 별칭이 있으면 XNUMX이 아닙니다.
가득 찬 ICO정보제출 of 핵심 타입맵
각 C 유형은 다음을 담당하는 typemap 파일의 항목으로 표시됩니다.
펄 변수(SV, AV, HV, CV 등)를 해당 유형으로 변환합니다. 다음과 같은
섹션은 기본적으로 perl과 함께 제공되는 모든 XS 유형을 나열합니다.
T_SV
이것은 단순히 Perl 변수(SV*)의 C 표현을 안팎으로 전달합니다.
XS 레이어. 이것은 C 코드가 Perl을 직접 다루기를 원할 때 사용할 수 있습니다.
변하기 쉬운.
T_SVREF
SV에 대한 참조를 전달하고 반환하는 데 사용됩니다.
이 typemap은 반환할 때 참조 횟수를 감소시키지 않습니다.
SV*에 대한 참조. 참조: T_SVREF_REFCOUNT_FIXED
T_SVREF_FIXED
SV에 대한 참조를 전달하고 반환하는 데 사용됩니다. 이것은 T_SVREF의 고정된 변형입니다.
SV*에 대한 참조를 반환할 때 refcount를 적절하게 감소시킵니다.
Perl 5.15.4에 도입되었습니다.
T_AVREF
펄 레벨에서 이것은 펄 어레이에 대한 참조입니다. C 레벨에서 이것은
AV에 대한 포인터.
이 typemap은 AV*를 반환할 때 참조 카운트를 감소시키지 않습니다.
참조: T_AVREF_REFCOUNT_FIXED
T_AVREF_REFCOUNT_FIXED
펄 레벨에서 이것은 펄 어레이에 대한 참조입니다. C 레벨에서 이것은
AV에 대한 포인터. 이것은 refcount를 감소시키는 T_AVREF의 고정된 변형입니다.
AV*를 반환할 때 적절하게. Perl 5.15.4에 도입되었습니다.
T_HVREF
펄 레벨에서 이것은 펄 해시에 대한 참조입니다. C 레벨에서 이것은
HV에 대한 포인터.
이 typemap은 HV*를 반환할 때 참조 카운트를 감소시키지 않습니다.
참조: T_HVREF_REFCOUNT_FIXED
T_HVREF_REFCOUNT_FIXED
펄 레벨에서 이것은 펄 해시에 대한 참조입니다. C 레벨에서 이것은
HV에 대한 포인터. 이것은 refcount를 감소시키는 T_HVREF의 고정된 변형입니다.
HV*를 반환할 때 적절하게. Perl 5.15.4에 도입되었습니다.
T_CVREF
펄 레벨에서 이것은 펄 서브루틴에 대한 참조입니다(예: $sub = sub { 1 };).
C 레벨에서 이것은 CV에 대한 포인터입니다.
이 typemap은 HV*를 반환할 때 참조 카운트를 감소시키지 않습니다.
참조: T_HVREF_REFCOUNT_FIXED
T_CVREF_REFCOUNT_FIXED
펄 레벨에서 이것은 펄 서브루틴에 대한 참조입니다(예: $sub = sub { 1 };).
C 레벨에서 이것은 CV에 대한 포인터입니다.
이것은 다음과 같은 경우 refcount를 적절하게 감소시키는 T_HVREF의 고정 변형입니다.
HV*를 반환합니다. Perl 5.15.4에 도입되었습니다.
T_SYSRET
T_SYSRET typemap은 시스템 호출에서 반환 값을 처리하는 데 사용됩니다. 이건 그냥
C에서 perl로 값을 전달할 때 의미 있음(시스템 전달에 대한 개념 없음
Perl에서 C로 값을 반환).
시스템 호출은 오류 시 -1을 반환하고(이유와 함께 ERRNO 설정) (보통) 오류 시 0을 반환합니다.
성공. 반환 값이 -1이면 이 typemap은 "undef"를 반환합니다. 반환 값의 경우
-1이 아닌 경우 이 typemap은 0(perl false)을 "0이지만 true"(perl임)로 변환합니다.
true) 또는 값 자체를 반환하여 명령이 성공했음을 나타냅니다.
POSIX 모듈은 이 유형을 광범위하게 사용합니다.
T_UV
부호 없는 정수입니다.
T_IV
부호 있는 정수입니다. 이것은 C에 전달될 때 필요한 정수 유형으로 캐스트되고
Perl로 다시 전달되면 IV로 변환됩니다.
색조
부호 있는 정수입니다. 이 typemap은 Perl 값을 기본 정수 유형으로 변환합니다(
현재 플랫폼의 "int" 유형). 값을 perl에 반환할 때 처리됩니다.
T_IV와 같은 방식으로.
동작은 T_IV와 함께 XS에서 "int" 유형을 사용하는 것과 동일합니다.
T_ENUM
열거형 값입니다. C에서 enum 구성 요소를 전송하는 데 사용됩니다. 전달할 이유가 없습니다.
펄 내부에 IV로 저장되기 때문에 열거형 값을 C로 지정합니다.
T_BOOL
부울 유형입니다. 이것은 C에서 true 및 false 값을 전달하는 데 사용할 수 있습니다.
T_U_INT
이것은 부호 없는 정수를 위한 것입니다. T_UV를 사용하는 것과 동일하지만 명시적으로 캐스팅합니다.
"unsigned int"를 입력할 변수입니다. "unsigned int"의 기본 유형은 T_UV입니다.
T_단축
짧은 정수. 이것은 T_IV와 동일하지만 명시적으로 리턴을 유형으로 캐스트합니다.
"짧은". "short"의 기본 typemap은 T_IV입니다.
T_U_SHORT
부호 없는 짧은 정수. 이것은 T_UV와 동일하지만 명시적으로 리턴을 캐스트합니다.
"unsigned short"를 입력합니다. "unsigned short"의 기본 typemap은 T_UV입니다.
T_U_SHORT는 표준 typemap에서 "U16" 유형에 사용됩니다.
T_롱
긴 정수. 이것은 T_IV와 동일하지만 명시적으로 리턴을 유형으로 캐스트합니다.
"긴". "long"의 기본 typemap은 T_IV입니다.
T_U_롱
부호 없는 긴 정수. 이것은 T_UV와 동일하지만 명시적으로 리턴을 캐스트합니다.
"unsigned long"을 입력합니다. "unsigned long"의 기본 typemap은 T_UV입니다.
T_U_LONG은 표준 typemap에서 "U32" 유형에 사용됩니다.
T_CHAR
단일 8비트 문자.
T_U_CHAR
부호 없는 바이트.
티_플로트
부동 소수점 숫자입니다. 이 typemap은 변수 캐스트를 반환하도록 보장합니다.
"뜨다".
T_NV
Perl 부동 소수점 숫자. 반환 유형이 캐스트된다는 점에서 T_IV 및 T_UV와 유사합니다.
특정 유형이 아닌 요청된 숫자 유형으로.
T_DOUBLE
배정밀도 부동 소수점 숫자입니다. 이 typemap은 변수 반환을 보장합니다.
"더블"로 캐스팅합니다.
T_PV
문자열(char *).
T_PTR
메모리 주소(포인터). 일반적으로 "void *" 유형과 연결됩니다.
T_PTRREF
포인터가 스칼라에 저장되고
해당 스칼라는 호출자에게 반환됩니다. 이것은 실제 포인터를 숨기는 데 사용할 수 있습니다.
일반적으로 Perl 내에서 직접 필요하지 않기 때문에 프로그래머로부터 값을 가져옵니다.
typemap은 스칼라 참조가 perl에서 XS로 전달되는지 확인합니다.
T_PTOBJ
참조가 클래스로 축복된다는 점을 제외하고는 T_PTRREF와 유사합니다. 이것은 허용
개체로 사용할 포인터입니다. C 구조체를 처리하는 데 가장 일반적으로 사용됩니다. 그만큼
typemap은 XS 루틴에 전달된 perl 객체가 올바른 클래스인지 확인합니다.
(또는 하위 클래스의 일부).
포인터는 유형의 이름에서 파생된 클래스에 축복을 받았습니다.
포인터이지만 이름의 모든 '*'는 'Ptr'로 대체되었습니다.
"DESTROY" XSUB의 경우에만 T_PTROBJ가 T_PTRREF에 최적화됩니다. 이것은 클래스를 의미합니다
확인을 건너뜁니다.
T_REF_IV_REF
아직
T_REF_IV_PTR
포인터가 스칼라 객체로 축복된다는 점에서 T_PTOBJ와 유사합니다. 그만큼
차이점은 객체가 XS로 다시 전달될 때 올바른 객체여야 한다는 것입니다.
유형(상속은 지원되지 않음)인 반면 T_PTOBJ는 상속을 지원합니다.
포인터는 유형의 이름에서 파생된 클래스에 축복을 받았습니다.
포인터이지만 이름의 모든 '*'는 'Ptr'로 대체되었습니다.
"DESTROY" XSUB의 경우에만 T_REF_IV_PTR이 T_PTRREF에 최적화됩니다. 이것은 다음을 의미합니다
클래스 확인을 건너뜁니다.
T_PTRDESC
아직
T_REFREF
참조된 스칼라에 저장된 포인터가
역참조되고 출력 변수에 복사됩니다. 이것은 T_REFREF가
T_OPAQUE로서의 T_PTRREF는 T_OPAQUEPTR입니다. 공습 경보 해제?
이것의 INPUT 부분만 구현되며(Perl에서 XSUB로) 알려진 사용자가 없습니다.
코어 또는 CPAN에서.
T_REFOBJ
엄격한 유형 검사를 수행한다는 점을 제외하고 T_REFREF와 유사합니다(상속은 지원되지 않음).
"DESTROY" XSUB의 경우에만 T_REFOBJ가 T_REFREF에 최적화됩니다. 이것은 클래스를 의미합니다
확인을 건너뜁니다.
T_OPAQUEPTR
이것은 SV의 문자열 구성 요소에 바이트를 저장하는 데 사용할 수 있습니다. 여기서
데이터 표현은 perl과 관련이 없으며 바이트 자체는
SV에 저장됩니다. C 변수가 포인터라고 가정합니다(바이트는 복사됩니다.
해당 메모리 위치에서). 포인터가 다음을 가리키는 경우
8바이트로 표시되면 해당 8바이트는 SV에 저장됩니다(및 길이() 결제 게이트웨이,
8)의 값을 보고합니다. 이 항목은 T_OPAQUE와 유사합니다.
원칙적으로 풀다() 명령을 사용하여 바이트를 다시 숫자로 변환할 수 있습니다.
(기본 유형이 숫자로 알려진 경우).
이 항목은 C 구조를 저장하는 데 사용할 수 있습니다(복사할 바이트 수는
C "sizeof" 함수를 사용하여 계산됨)
메모리 누수에 대해 걱정할 필요 없이 T_PTRREF(Perl이
SV).
T_불투명
이것은 SV의 문자열 부분에 포인터가 아닌 유형의 데이터를 저장하는 데 사용할 수 있습니다. 그것
typemap이 포인터를 직접 검색한다는 점을 제외하고는 T_OPAQUEPTR와 유사합니다.
공급되고 있다고 생각하기 보다는. 예를 들어 정수를 다음으로 가져온 경우
정수를 나타내는 기본 바이트 T_IV 대신 T_OPAQUE를 사용하는 Perl
SV에 저장되지만 실제 정수 값은 사용할 수 없습니다. 즉
데이터는 perl에 불투명합니다.
기본 유형의 경우 "unpack" 기능을 사용하여 데이터를 검색할 수 있습니다.
바이트 스트림이 알려져 있습니다.
T_OPAQUE는 단순 유형의 입력 및 출력을 지원합니다. T_OPAQUEPTR를 사용하여 통과할 수 있습니다.
포인터가 허용되는 경우 이 바이트를 C로 되돌립니다.
암시적 배열
xsubpp는 압축된 C 배열을 펄로 반환하기 위한 특수 구문을 지원합니다. XS의 경우
반환 유형은 다음과 같이 지정됩니다.
배열(유형, nelem)
xsubpp는 "nelem * sizeof(type)" 바이트의 내용을 RETVAL에서 SV로 복사하고
스택에 푸시합니다. 이것은 항목의 수가 있는 경우에만 정말 유용합니다.
반환된 값은 컴파일 시간에 알려지며 파일에 바이트 문자열이 있어도 상관 없습니다.
SV. T_ARRAY를 사용하여 가변 개수의 인수를 반환 스택에 푸시합니다.
그러나 단일 문자열로 포장되지는 않습니다).
이것은 T_OPAQUEPTR를 사용하는 것과 유사하지만 둘 이상의 요소를 처리하는 데 사용할 수 있습니다.
T_PACKED
변환을 위해 사용자 제공 함수를 호출합니다. "OUTPUT"(XSUB에서 Perl로)의 경우 함수
"XS_pack_$ntype"이라는 이름이 출력 Perl 스칼라 및 C 변수와 함께 호출됩니다.
에서 변환합니다. $ntype은 Perl에 매핑되는 정규화된 C 유형입니다.
정규화는 모든 "*"가 문자열 "Ptr"로 대체됨을 의미합니다. 반환 값
함수는 무시됩니다.
반대로 "INPUT"(Perl에서 XSUB로) 매핑의 경우 "XS_unpack_$ntype"이라는 함수
입력 Perl 스칼라를 인수로 사용하여 호출되고 반환 값은
매핑된 C 유형 및 출력 C 변수에 할당됩니다.
유형 매핑된 구조체 "foo_t *"에 대한 변환 함수의 예는 다음과 같습니다.
정적 공극
XS_pack_foo_tPtr(SV *출력, foo_t *입력)
{
dTHX; /* 아아, 서명은 pTHX_를 포함하지 않습니다 */
HV* 해시 = newHV();
hv_stores(해시, "int_member", newSViv(in->int_member));
hv_stores(해시, "float_member", newSVnv(in->float_member));
/* ... */
/* 스택이 다시 계산되지 않으므로 치명상을 입힙니다. */
sv_setsv(out, sv_2mortal(newRV_noinc((SV*)hash)));
}
Perl에서 C로의 변환은 독자에게 연습으로 남겨두지만 프로토타입
다음과 같습니다.
정적 foo_t *
XS_unpack_foo_tPtr(SV *in);
"dTHX"를 사용하여 스레드 컨텍스트를 가져와야 하는 실제 C 함수 대신
같은 이름의 매크로를 정의하고 오버헤드를 피할 수 있습니다. 또한 다음 사항에 유의하십시오.
"XS_unpack_foo_tPtr"에 의해 할당된 메모리를 해제할 수 있습니다.
T_PACKEDARRAY
T_PACKEDARRAY는 T_PACKED와 유사합니다. 사실, "INPUT"(Perl에서 XSUB로) typemap은
동일하지만 "OUTPUT" typemap은 추가 인수를
"XS_pack_$ntype" 기능. 이 세 번째 매개변수는 요소의 수를 나타냅니다.
함수가 C 배열을 올바르게 처리할 수 있도록 출력합니다. 변수는 다음과 같아야 합니다.
사용자가 선언하고 "count_$ntype"이라는 이름을 가져야 합니다. 여기서 $ntype은
위에서 설명한 대로 정규화된 C 유형 이름입니다. 함수의 서명은 다음을 위한 것입니다.
위의 예와 "foo_t **":
정적 공극
XS_pack_foo_tPtrPtr(SV *out, foo_t *in, UV count_foo_tPtrPtr);
세 번째 매개변수의 유형은 typemap에 관한 한 임의입니다. 그것
선언된 변수와 일치해야 합니다.
물론 "sometype **" C 배열의 요소 수를 알지 못하면
XSUB에서 "foo_t ** XS_unpack_foo_tPtrPtr(...)"의 반환 값은
풀다. 세부 사항은 모두 XS 작성자(typemap 사용자)에게 달려 있으므로
몇 가지 솔루션 중 특히 우아한 것은 없습니다. 가장 흔히 볼 수 있는
해결책은 N+1 포인터에 대한 메모리를 할당하고 (N+1)번째 포인터에 "NULL"을 할당하는 것입니다.
반복을 용이하게 하기 위해.
또는 처음에 목적에 맞게 사용자 정의된 typemap을 사용하는 것은
아마도 바람직합니다.
T_DATAUNIT
아직
T_콜백
아직
T_ARRAY
이것은 perl 인수 목록을 C 배열로 변환하고 푸시하는 데 사용됩니다.
C 배열의 내용을 perl 인수 스택에 저장합니다.
일반적인 호출 서명은
@out = array_func( @in );
배열 앞의 목록에서 임의의 수의 인수가 발생할 수 있지만 입력 및
출력 배열은 목록의 마지막 요소여야 합니다.
Perl 목록을 C에 전달하는 데 사용되는 경우 XS 작성자는 기능을 제공해야 합니다(이름은
배열 유형이지만 '*'를 'Ptr'로 대체)에 필요한 메모리 할당
목록을 보유하십시오. 포인터가 반환되어야 합니다. 풀어주는 것은 XS 작가의 몫이다.
함수 종료 시 메모리. 변수 "ix_$var"는 다음 수로 설정됩니다.
새 배열의 요소.
C 배열을 Perl에 반환할 때 XS 작성자는 다음과 같은 정수 변수를 제공해야 합니다.
배열의 요소 수를 포함하는 "size_$var". 이것은 결정하는 데 사용됩니다
반환 인수 스택에 푸시해야 하는 요소의 수. 이것은 아니다
Perl은 스택에 있는 인수의 수를 알고 있기 때문에 입력에 필요합니다.
루틴이 호출됩니다. 일반적으로 이 변수는 "size_RETVAL"이라고 합니다.
또한 각 요소의 유형은 배열 유형에 따라 결정됩니다. 만약에
배열은 "intArray *" 유형을 사용합니다. xsubpp는 자동으로 포함된 내용을 확인합니다.
"int" 유형의 변수를 만들고 해당 typemap 항목을 사용하여 각 항목의 복사를 수행합니다.
요소. 모든 포인터 '*' 및 '배열' 태그는 이름에서 제거되어
하위 유형.
T_STDIO
이것은 "FILE *" 구조를 사용하여 C에서 Perl 파일 핸들을 전달하는 데 사용됩니다.
T_INOUT
이것은 "PerlIO *" 구조를 사용하여 C에서 Perl 파일 핸들을 전달하는 데 사용됩니다.
파일 핸들은 읽기 및 쓰기에 사용할 수 있습니다. 이것은 "+<" 모드에 해당하며,
T_IN 및 T_OUT도 참조하십시오.
Perl IO 추상화 계층에 대한 자세한 내용은 perliol을 참조하십시오. 펄은 틀림없이
"-Duseperlio"로 제작되었습니다.
Perl에서 C로 전달된 파일 핸들이
올바른 "open()" 모드.
힌트: perlxstut 튜토리얼은 T_INOUT, T_IN, T_OUT XS 유형을 훌륭하게 다룹니다.
주석
T_INOUT과 같지만 C에서 Perl로 반환되는 파일 핸들만 사용할 수 있습니다.
읽기용(모드 "<").
암표 장수
T_INOUT과 같지만 C에서 Perl로 반환되는 파일 핸들은 다음을 사용하도록 설정됩니다.
오픈 모드 "+>".
onworks.net 서비스를 사용하여 온라인으로 perlxstypemap 사용