Đây là lệnh perlxstypemap có thể chạy trong nhà cung cấp dịch vụ lưu trữ miễn phí OnWorks bằng cách sử dụng một trong nhiều máy trạm trực tuyến miễn phí của chúng tôi như Ubuntu Online, Fedora Online, trình giả lập trực tuyến Windows hoặc trình giả lập trực tuyến MAC OS
CHƯƠNG TRÌNH:
TÊN
perlxstypemap - Ánh xạ loại Perl XS C / Perl
MÔ TẢ
Bạn càng nghĩ nhiều về giao diện giữa hai ngôn ngữ, bạn càng nhận ra rằng
phần lớn nỗ lực của lập trình viên phải chuyển đổi giữa các cấu trúc dữ liệu
có nguồn gốc từ một trong các ngôn ngữ có liên quan. Điều này vượt trội các vấn đề khác, chẳng hạn như
quy ước gọi khác nhau bởi vì không gian vấn đề lớn hơn rất nhiều. Có
đơn giản là nhiều cách để chuyển dữ liệu vào bộ nhớ hơn là có nhiều cách để triển khai một hàm
gọi.
Perl XS 'cố gắng tìm ra giải pháp cho vấn đề này là khái niệm về sơ đồ chính tả. Ở cấp độ trừu tượng,
một bản đồ chính tả Perl XS không là gì khác ngoài một công thức để chuyển đổi từ một dữ liệu Perl nhất định
cấu trúc thành một cấu trúc dữ liệu C nhất định và ngược lại. Vì có thể có loại C mà
đủ tương tự với nhau để đảm bảo chuyển đổi với cùng một logic, XS
các bản đồ chính tả được đại diện bởi một số nhận dạng duy nhất, do đó, về sau được gọi là XS kiểu trong
tài liệu. Sau đó, bạn có thể cho trình biên dịch XS biết rằng nhiều loại C sẽ được ánh xạ với
cùng một bản đồ chính tả XS.
Trong mã XS của bạn, khi bạn xác định đối số bằng loại C hoặc khi bạn đang sử dụng "CODE:"
và phần "OUTPUT:" cùng với loại trả về C của XSUB, nó sẽ là
cơ chế đánh máy giúp việc này trở nên dễ dàng.
Giải Phẫu of a sơ đồ đánh máy
Nói một cách thực tế hơn, sơ đồ đánh máy là một tập hợp các đoạn mã được sử dụng bởi
các xsubpp trình biên dịch để ánh xạ các tham số và giá trị của hàm C thành giá trị Perl. Bản đồ chính tả
tệp có thể bao gồm ba phần có nhãn "TYPEMAP", "INPUT" và "OUTPUT". Một
phần ban đầu không có nhãn được giả định là phần "TYPEMAP". Phần INPUT cho biết
trình biên dịch làm thế nào để dịch các giá trị Perl thành các biến của các loại C nhất định. Đầu ra
phần cho trình biên dịch biết cách dịch các giá trị từ các loại C nhất định thành các giá trị
Perl có thể hiểu. Phần TYPEMAP cho trình biên dịch biết INPUT và OUTPUT nào
các đoạn mã nên được sử dụng để ánh xạ một loại C nhất định với một giá trị Perl. Các nhãn phần
"TYPEMAP", "INPUT" hoặc "OUTPUT" phải tự bắt đầu ở cột đầu tiên trên một dòng,
và phải được viết hoa.
Mỗi loại phần có thể xuất hiện số lần tùy ý và không nhất thiết phải xuất hiện
ở tất cả. Ví dụ: một sơ đồ chính tả có thể thường thiếu các phần "INPUT" và "OUTPUT" nếu tất cả
việc cần làm là liên kết các loại C bổ sung với các loại XS cốt lõi như T_PTROBJ. Dòng đó
bắt đầu bằng băm "#" được coi là nhận xét và bị bỏ qua trong phần "TYPEMAP", nhưng
được coi là quan trọng trong "INPUT" và "OUTPUT". Các dòng trống thường bị bỏ qua.
Theo truyền thống, các sơ đồ đánh máy cần được ghi vào một tệp riêng biệt, thường được gọi là
"typemap" trong bản phân phối CPAN. Với ExtUtils :: ParseXS (trình biên dịch XS) phiên bản 3.12
hoặc tốt hơn đi kèm với perl 5.16, các sơ đồ chính tả cũng có thể được nhúng trực tiếp vào mã XS
sử dụng cú pháp như HERE-doc:
TYPEMAP: <
...
tại ĐÂY
trong đó "HERE" có thể được thay thế bằng các số nhận dạng khác như với Perl HERE-docs thông thường. Tất cả các
chi tiết bên dưới về định dạng văn bản của sơ đồ đánh máy vẫn còn hiệu lực.
Phần "TYPEMAP" phải chứa một cặp loại C và loại XS trên mỗi dòng như sau.
Một ví dụ từ tệp bản đồ chính:
SƠ ĐỒ LOẠI
# tất cả các biến thể của char * được xử lý bởi T_PV typemap
ký tự * T_PV
const char * T_PV
ký tự không dấu * T_PV
...
Phần "INPUT" và "OUTPUT" có định dạng giống hệt nhau, nghĩa là mỗi dòng không có dấu
bắt đầu một bản đồ đầu vào hoặc đầu ra mới tương ứng. Một bản đồ đầu vào hoặc đầu ra mới phải bắt đầu bằng
tên của loại XS để tự ánh xạ trên một dòng, theo sau là mã triển khai nó
thụt lề trên các dòng sau. Thí dụ:
ĐẦU VÀO
T_PV
$ var = ($ type) SvPV_nolen ($ arg)
T_PTR
$ var = INT2PTR ($ type, SvIV ($ arg))
Chúng ta sẽ tìm hiểu ý nghĩa của các biến trông Perlish đó sau một chút nữa.
Cuối cùng, đây là một ví dụ về tệp chính tả đầy đủ để ánh xạ chuỗi C của "char *"
gõ vào vô hướng Perl / chuỗi:
SƠ ĐỒ LOẠI
ký tự * T_PV
ĐẦU VÀO
T_PV
$ var = ($ type) SvPV_nolen ($ arg)
OUTPUT
T_PV
sv_setpv ((SV *) $ arg, $ var);
Đây là một ví dụ phức tạp hơn: giả sử rằng bạn muốn "struct netconfig" là
phước vào lớp "Net :: Config". Một cách để làm điều này là sử dụng dấu gạch dưới (_) để
tên gói riêng biệt, như sau:
typedef struct netconfig * Net_Config;
Và sau đó cung cấp mục nhập bản đồ chính tả "T_PTROBJ_SPECIAL" ánh xạ dấu gạch dưới thành dấu hai chấm
(: :) và khai báo "Net_Config" thuộc loại đó:
SƠ ĐỒ LOẠI
Net_Config T_PTROBJ_SPECIAL
ĐẦU VÀO
T_PTROBJ_SPECIAL
if (sv_derived_from ($ arg, \ "$ {(my $ ntt = $ ntype) = ~ s / _ / :: / g; \ $ ntt} \")) {
IV tmp = SvIV ((SV *) SvRV ($ arg));
$ var = INT2PTR ($ type, tmp);
}
khác
croak (\ "$ var không thuộc loại $ {($ ntt = $ ntype của tôi) = ~ s / _ / :: / g; \ $ ntt} \")
OUTPUT
T_PTROBJ_SPECIAL
sv_setref_pv ($ arg, \ "$ {($ ntt = $ ntype của tôi) = ~ s / _ / :: / g; \ $ ntt} \",
(void *) $ var);
Phần INPUT và OUTPUT thay thế dấu gạch dưới cho dấu hai chấm khi đang bay, cho
hiệu quả mong muốn. Ví dụ này cho thấy một số sức mạnh và tính linh hoạt của
cơ sở đánh máy.
Macro "INT2PTR" (được định nghĩa trong perl.h) truyền một số nguyên tới một con trỏ của một loại nhất định,
quan tâm đến kích thước khác nhau có thể có của số nguyên và con trỏ. Cũng có
Macro "PTR2IV", "PTR2UV", "PTR2NV", để ánh xạ theo cách khác, có thể hữu ích trong OUTPUT
phần.
Vai trò of các sơ đồ đánh máy Tập tin in trên màn hình phân phát
Bản đồ chính tả mặc định trong lib / ExtUtils thư mục của nguồn Perl chứa nhiều
các loại có thể được sử dụng bởi phần mở rộng Perl. Một số tiện ích mở rộng xác định các sơ đồ chính tả bổ sung
mà họ giữ trong thư mục riêng của họ. Các sơ đồ chính tả bổ sung này có thể tham chiếu đến INPUT và
Bản đồ OUTPUT trong bản đồ chính. Các xsubpp trình biên dịch sẽ cho phép phần mở rộng của riêng
typemap để ghi đè bất kỳ ánh xạ nào có trong typemap mặc định. Thay vì sử dụng một
bổ sung sơ đồ đánh máy tệp, sơ đồ chính tả có thể được nhúng nguyên văn trong XS với một heredoc giống như
cú pháp. Xem tài liệu về từ khóa "TYPEMAP:" XS.
Đối với các bản phân phối CPAN, bạn có thể giả định rằng các loại XS được xác định bởi lõi perl là
đã có sẵn. Ngoài ra, bản đồ chính có các loại XS mặc định cho một số lượng lớn
của C loại. Ví dụ: nếu bạn chỉ trả về một "char *" từ XSUB của mình, thì bản đồ chính
sẽ có loại C này được liên kết với loại XS T_PV. Điều đó có nghĩa là chuỗi C của bạn sẽ là
được sao chép vào vị trí PV (giá trị con trỏ) của một đại lượng vô hướng mới sẽ được trả về từ
XSUB sang Perl.
Nếu bạn đang phát triển phân phối CPAN bằng XS, bạn có thể thêm tệp của riêng mình có tên
sơ đồ đánh máy để phân phối. Tệp đó có thể chứa các bản đồ đánh máy mà bản đồ loại
dành riêng cho mã của bạn hoặc ghi đè ánh xạ của tệp sơ đồ chính xác cho C chung
các loại.
Chia sẻ sơ đồ đánh máy Giữa CPAN Phân phối
Bắt đầu với ExtUtils :: ParseXS phiên bản 3.13_01 (đi kèm với perl 5.16 và tốt hơn), nó là
khá dễ dàng để chia sẻ mã typemap giữa nhiều bản phân phối CPAN. Ý tưởng chung là
để chia sẻ nó dưới dạng một mô-đun cung cấp một API nhất định và có các mô-đun phụ thuộc khai báo
đó là yêu cầu về thời gian xây dựng và nhập bản đồ đánh máy vào XS. Một ví dụ về một
mô-đun chia sẻ typemap trên CPAN là "ExtUtils :: Typemaps :: Basic". Hai bước để đạt được điều đó
các sơ đồ chính tả của mô-đun có sẵn trong mã của bạn:
· Khai báo "ExtUtils :: Typemaps :: Basic" dưới dạng phụ thuộc thời gian xây dựng trong "Makefile.PL" (sử dụng
"BUILD_REQUIRES") hoặc trong "Build.PL" của bạn (sử dụng "build_requires").
· Bao gồm dòng sau trong phần XS của tệp XS của bạn: (không ngắt dòng)
INCLUDE_COMMAND: $ ^ X -MExtUtils :: Typemaps :: Cmd
-e "print nhúngdable_typemap (q {Basic})"
Writing sơ đồ đánh máy Mục
Mỗi mục nhập định dạng INPUT hoặc OUTPUT là một chuỗi Perl được trích dẫn kép sẽ được đánh giá
với sự hiện diện của các biến nhất định để lấy mã C cuối cùng để ánh xạ một loại C nhất định.
Điều này có nghĩa là bạn có thể nhúng mã Perl vào mã typemap (C) của mình bằng cách sử dụng các cấu trúc như
"Mã $ {perl đánh giá thành tham chiếu vô hướng tại đây}". Một trường hợp sử dụng phổ biến là tạo
thông báo lỗi tham chiếu đến tên hàm thực ngay cả khi sử dụng tính năng ALIAS XS:
$ {$ ALIAS? \ q [GvNAME (CvGV (cv))]: \ qq [\ "$ pname \"]}
Đối với nhiều ví dụ về sơ đồ chính tả, hãy tham khảo tệp sơ đồ chính tả có thể được tìm thấy trong perl
cây nguồn tại lib / ExtUtils / typemap.
Các biến Perl có sẵn để nội suy thành các sơ đồ chính tả như sau:
· $ var - tên của biến đầu vào hoặc đầu ra, ví dụ. RETVAL cho các giá trị trả về.
· $ loại - kiểu C thô của tham số, bất kỳ ":" được thay thế bằng "_". ví dụ cho một loại
của "Foo :: Bar", $ loại là "Foo__Bar"
· $ ntype - loại được cung cấp với "*" được thay thế bằng "Ptr". ví dụ: đối với một loại "Foo *",
$ ntype là "FooPtr"
· $ arg - mục nhập ngăn xếp, mà tham số được nhập từ hoặc đầu ra, ví dụ: ST(0)
· $ argoff - phần bù chồng đối số của đối số. I E. 0 cho đối số đầu tiên,
và vv
· $ pname - tên đầy đủ của XSUB, bao gồm cả tên "PACKAGE", với bất kỳ
"PREFIX" bị tước bỏ. Đây là tên không phải ALIAS.
· Gói $ - gói được chỉ định bởi từ khóa "PACKAGE" gần đây nhất.
· $ ALIAS - khác XNUMX nếu XSUB hiện tại có bất kỳ bí danh nào được khai báo bằng "ALIAS".
Full Liệt kê of Trung tâm Sơ đồ đánh máy
Mỗi loại C được đại diện bởi một mục nhập trong tệp sơ đồ đánh máy chịu trách nhiệm về
chuyển đổi các biến perl (SV, AV, HV, CV, v.v.) sang và từ loại đó. Sau
phần liệt kê tất cả các loại XS đi kèm với perl theo mặc định.
T_SV
Điều này chỉ đơn giản là chuyển biểu diễn C của biến Perl (SV *) vào và ra
lớp XS. Điều này có thể được sử dụng nếu mã C muốn giao dịch trực tiếp với Perl
biến.
T_SVREF
Được sử dụng để chuyển vào và trả về một tham chiếu đến SV.
Lưu ý rằng sơ đồ đánh máy này không làm giảm số lượng tham chiếu khi trả về
tham chiếu đến SV *. Xem thêm: T_SVREF_REFCOUNT_FIXED
T_SVREF_FIXED
Được sử dụng để chuyển vào và trả về một tham chiếu đến SV. Đây là một biến thể cố định của T_SVREF
điều đó làm giảm số tiền hoàn lại một cách thích hợp khi trả về một tham chiếu đến SV *.
Được giới thiệu trong perl 5.15.4.
T_AVREF
Từ mức perl, đây là một tham chiếu đến một mảng perl. Từ cấp độ C, đây là một
con trỏ đến một AV.
Lưu ý rằng sơ đồ đánh máy này không làm giảm số lượng tham chiếu khi trả về AV *.
Xem thêm: T_AVREF_REFCOUNT_FIXED
T_AVREF_REFCOUNT_FIXED
Từ mức perl, đây là một tham chiếu đến một mảng perl. Từ cấp độ C, đây là một
con trỏ đến một AV. Đây là một biến thể cố định của T_AVREF làm giảm số tiền tái cấp lại
thích hợp khi trả lại AV *. Được giới thiệu trong perl 5.15.4.
T_HVREF
Từ cấp perl, đây là một tham chiếu đến một hàm băm perl. Từ cấp độ C, đây là một
con trỏ tới một HV.
Lưu ý rằng sơ đồ đánh máy này không làm giảm số lượng tham chiếu khi trả về HV *.
Xem thêm: T_HVREF_REFCOUNT_FIXED
T_HVREF_REFCOUNT_FIXED
Từ cấp perl, đây là một tham chiếu đến một hàm băm perl. Từ cấp độ C, đây là một
con trỏ tới một HV. Đây là một biến thể cố định của T_HVREF làm giảm số tiền tái cấp lại
một cách thích hợp khi trả về một HV *. Được giới thiệu trong perl 5.15.4.
T_CVREF
Từ mức perl, đây là một tham chiếu đến một chương trình con perl (ví dụ: $ sub = sub {1};).
Từ cấp độ C, đây là một con trỏ đến một CV.
Lưu ý rằng sơ đồ đánh máy này không làm giảm số lượng tham chiếu khi trả về HV *.
Xem thêm: T_HVREF_REFCOUNT_FIXED
T_CVREF_REFCOUNT_FIXED
Từ mức perl, đây là một tham chiếu đến một chương trình con perl (ví dụ: $ sub = sub {1};).
Từ cấp độ C, đây là một con trỏ đến một CV.
Đây là một biến thể cố định của T_HVREF giúp giảm số tiền hoàn lại một cách thích hợp khi
trả về một HV *. Được giới thiệu trong perl 5.15.4.
T_SYSRET
Bản đồ định dạng T_SYSRET được sử dụng để xử lý các giá trị trả về từ các lệnh gọi hệ thống. Nó chỉ là
có ý nghĩa khi chuyển các giá trị từ C sang perl (không có khái niệm về việc truyền một hệ thống
trả về giá trị từ Perl đến C).
Lệnh gọi hệ thống trả về -1 trên lỗi (đặt ERRNO kèm theo lý do) và (thường) 0 khi bật
sự thành công. Nếu giá trị trả về là -1 thì bản đồ kiểu này trả về "undef". Nếu giá trị trả về
không phải là -1, bản đồ chính tả này dịch 0 (perl false) thành "0 but true" (là perl
true) hoặc trả về giá trị của chính nó, để chỉ ra rằng lệnh đã thành công.
Mô-đun POSIX sử dụng rộng rãi loại này.
T_UV
Một số nguyên không dấu.
T_IV
Một số nguyên có dấu. Điều này được chuyển thành kiểu số nguyên bắt buộc khi được chuyển tới C và
được chuyển đổi thành IV khi được chuyển trở lại Perl.
T_INT
Một số nguyên có dấu. Bản đồ kiểu này chuyển đổi giá trị Perl thành một kiểu số nguyên gốc (
loại "int" trên nền tảng hiện tại). Khi trả về giá trị perl, nó sẽ được xử lý
theo cách tương tự như đối với T_IV.
Hành vi của nó giống với việc sử dụng kiểu "int" trong XS với T_IV.
T_ENUM
Một giá trị enum. Được sử dụng để chuyển một thành phần enum từ C. Không có lý do gì để chuyển
một giá trị enum thành C vì nó được lưu trữ dưới dạng IV bên trong perl.
T_BOOL
Một kiểu boolean. Điều này có thể được sử dụng để chuyển các giá trị đúng và sai đến và đi từ C.
T_U_INT
Điều này dành cho các số nguyên không dấu. Nó tương đương với việc sử dụng T_UV nhưng truyền một cách rõ ràng
biến thành kiểu "unsigned int". Loại mặc định cho "int unsigned" là T_UV.
T_SHORT
Số nguyên ngắn. Điều này tương đương với T_IV nhưng truyền trả về loại một cách rõ ràng
"ngắn". Bản đồ chính tả mặc định cho "short" là T_IV.
T_U_SHORT
Số nguyên ngắn không dấu. Điều này tương đương với T_UV nhưng chuyển trả về một cách rõ ràng
gõ "không dấu ngắn". Bản đồ chính tả mặc định cho "chữ viết tắt không dấu" là T_UV.
T_U_SHORT được sử dụng cho loại "U16" trong bản đồ chính tả tiêu chuẩn.
T_DÀI
Số nguyên dài. Điều này tương đương với T_IV nhưng truyền trả về loại một cách rõ ràng
"Dài". Bản đồ chính tả mặc định cho "long" là T_IV.
T_U_LONG
Số nguyên dài không dấu. Điều này tương đương với T_UV nhưng chuyển trả về một cách rõ ràng
gõ "unsigned long". Bản đồ chính tả mặc định cho "unsigned long" là T_UV.
T_U_LONG được sử dụng cho kiểu "U32" trong bản đồ chuẩn.
T_CHAR
Các ký tự 8 bit đơn.
T_U_CHAR
Một byte không dấu.
T_FLOAT
Một số dấu phẩy động. Bản đồ định dạng này đảm bảo trả về một biến truyền thành một
"trôi nổi".
T_NV
Một số dấu phẩy động Perl. Tương tự như T_IV và T_UV ở chỗ kiểu trả về được ép kiểu
cho loại số được yêu cầu thay vì một loại cụ thể.
T_NHÂN ĐÔI
Một số dấu phẩy động chính xác gấp đôi. Bản đồ chính tả này đảm bảo trả về một biến
truyền đến một "kép".
T_PV
Một chuỗi (ký tự *).
T_PTR
Một địa chỉ bộ nhớ (con trỏ). Thường được liên kết với kiểu "void *".
T_PTRREF
Tương tự như T_PTR ngoại trừ việc con trỏ được lưu trữ trong một đại lượng vô hướng và tham chiếu đến
vô hướng đó được trả lại cho người gọi. Điều này có thể được sử dụng để ẩn con trỏ thực tế
giá trị từ lập trình viên vì nó thường không được yêu cầu trực tiếp từ bên trong perl.
Bản đồ đánh máy kiểm tra xem một tham chiếu vô hướng có được chuyển từ perl sang XS hay không.
T_PTROBJ
Tương tự như T_PTRREF ngoại trừ việc tham chiếu được tạo thành một lớp. Điều này cho phép
con trỏ được sử dụng như một đối tượng. Thường được sử dụng nhất để xử lý các cấu trúc C. Các
typemap kiểm tra xem đối tượng perl được truyền vào quy trình XS có thuộc lớp chính xác hay không
(hoặc một phần của lớp con).
Con trỏ được tạo thành một lớp có nguồn gốc từ tên kiểu của
con trỏ nhưng với tất cả '*' trong tên được thay thế bằng 'Ptr'.
Chỉ đối với XSUB "DESTROY", T_PTROBJ được tối ưu hóa thành T_PTRREF. Điều này có nghĩa là lớp
kiểm tra bị bỏ qua.
T_REF_IV_REF
CHƯA
T_REF_IV_PTR
Tương tự như T_PTROBJ ở chỗ con trỏ được biến thành một đối tượng vô hướng. Các
sự khác biệt là khi đối tượng được chuyển trở lại XS nó phải đúng
loại (kế thừa không được hỗ trợ) trong khi T_PTROBJ hỗ trợ kế thừa.
Con trỏ được tạo thành một lớp có nguồn gốc từ tên kiểu của
con trỏ nhưng với tất cả '*' trong tên được thay thế bằng 'Ptr'.
Chỉ đối với XSUB "DESTROY", T_REF_IV_PTR được tối ưu hóa thành T_PTRREF. Điều này có nghĩa là
kiểm tra lớp bị bỏ qua.
T_PTRDESC
CHƯA
T_REFREF
Tương tự như T_PTRREF, ngoại trừ con trỏ được lưu trữ trong đại lượng vô hướng được tham chiếu là
được tham chiếu và sao chép vào biến đầu ra. Điều này có nghĩa là T_REFREF phải
T_PTRREF dưới dạng T_OPAQUE là T_OPAQUEPTR. Tất cả rõ ràng?
Chỉ phần INPUT của điều này được triển khai (Perl đến XSUB) và không có người dùng nào được biết đến
trong lõi hoặc trên CPAN.
T_REFOBJ
Giống như T_REFREF, ngoại trừ việc kiểm tra kiểu nghiêm ngặt (không hỗ trợ tính kế thừa).
Chỉ đối với XSUB "DESTROY", T_REFOBJ được tối ưu hóa thành T_REFREF. Điều này có nghĩa là lớp
kiểm tra bị bỏ qua.
T_OPAQUEPTR
Điều này có thể được sử dụng để lưu trữ các byte trong thành phần chuỗi của SV. Đây
biểu diễn dữ liệu không liên quan đến perl và bản thân các byte chỉ là
được lưu trữ trong SV. Giả định rằng biến C là một con trỏ (các byte được sao chép
từ vị trí bộ nhớ đó). Nếu con trỏ đang trỏ đến một cái gì đó
được đại diện bởi 8 byte thì 8 byte đó được lưu trữ trong SV (và chiều dài() sẽ
báo cáo giá trị là 8). Mục nhập này tương tự như T_OPAQUE.
Về nguyên tắc giải nén () lệnh có thể được sử dụng để chuyển đổi các byte trở lại một số
(nếu kiểu cơ bản được biết là một số).
Mục nhập này có thể được sử dụng để lưu trữ cấu trúc C (số byte được sao chép là
được tính bằng cách sử dụng hàm C "sizeof") và có thể được sử dụng để thay thế cho
T_PTRREF mà không phải lo lắng về việc rò rỉ bộ nhớ (vì Perl sẽ dọn dẹp
SV).
T_OPAQUE
Điều này có thể được sử dụng để lưu trữ dữ liệu từ các loại không phải con trỏ trong phần chuỗi của SV. Nó
tương tự như T_OPAQUEPTR ngoại trừ việc bản đồ đánh máy truy xuất trực tiếp con trỏ
hơn là giả định rằng nó đang được cung cấp. Ví dụ: nếu một số nguyên được nhập vào
Perl sử dụng T_OPAQUE thay vì T_IV các byte bên dưới đại diện cho số nguyên
sẽ được lưu trữ trong SV nhưng giá trị số nguyên thực tế sẽ không có sẵn. tức là
dữ liệu không rõ ràng đối với perl.
Dữ liệu có thể được truy xuất bằng cách sử dụng chức năng "giải nén" nếu loại cơ bản của
luồng byte đã biết.
T_OPAQUE hỗ trợ đầu vào và đầu ra của các loại đơn giản. T_OPAQUEPTR có thể được sử dụng để vượt qua
các byte này trở lại C nếu một con trỏ được chấp nhận.
Mảng ẩn
xsubpp hỗ trợ một cú pháp đặc biệt để trả về mảng C đã đóng gói thành perl. Nếu XS
loại trả lại được đưa ra là
mảng (kiểu, nelem)
xsubpp sẽ sao chép nội dung của byte "nelem * sizeof (type)" từ RETVAL sang SV và
đẩy nó vào ngăn xếp. Điều này chỉ thực sự hữu ích nếu số lượng mục
trả về được xác định tại thời điểm biên dịch và bạn không ngại có một chuỗi byte trong
SV. Sử dụng T_ARRAY để đẩy một số lượng biến đối số lên ngăn xếp trả về (chúng
sẽ không được đóng gói dưới dạng một chuỗi duy nhất).
Điều này tương tự như sử dụng T_OPAQUEPTR nhưng có thể được sử dụng để xử lý nhiều phần tử.
T_ĐÓNG GÓI
Gọi các chức năng do người dùng cung cấp để chuyển đổi. Đối với "OUTPUT" (XSUB thành Perl), một hàm
có tên "XS_pack_ $ ntype" được gọi với đầu ra vô hướng Perl và biến C thành
chuyển đổi từ. $ ntype là kiểu C chuẩn hóa sẽ được ánh xạ tới Perl.
Chuẩn hóa có nghĩa là tất cả "*" được thay thế bằng chuỗi "Ptr". Giá trị trả về của
chức năng bị bỏ qua.
Ngược lại đối với ánh xạ "INPUT" (Perl đến XSUB), hàm có tên "XS_unpack_ $ ntype"
được gọi với tham số vô hướng Perl đầu vào và giá trị trả về được truyền đến
ánh xạ kiểu C và được gán cho biến C đầu ra.
Một chức năng chuyển đổi mẫu cho cấu trúc được đánh máy "foo_t *" có thể là:
khoảng trống tĩnh
XS_pack_foo_tPtr (SV * ra, foo_t * vào)
{
dTHX; / * than ôi, chữ ký không bao gồm pTHX_ * /
HV * hash = newHV ();
hv_stores (băm, "int_member", newSViv (in-> int_member));
hv_stores (băm, "float_member", newSVnv (in-> float_member));
/ * ... * /
/ * tiêu diệt vì ngăn xếp của bạn không được nạp lại * /
sv_setsv (out, sv_2mortal (newRV_noinc ((SV *) hash)));
}
Việc chuyển đổi từ Perl sang C được để lại như một bài tập cho người đọc, nhưng là nguyên mẫu
sẽ là:
foo_t tĩnh *
XS_unpack_foo_tPtr (SV * in);
Thay vì một hàm C thực tế phải tìm nạp ngữ cảnh luồng bằng "dTHX", bạn
có thể xác định các macro cùng tên và tránh phí tổn. Ngoài ra, hãy ghi nhớ
có thể giải phóng bộ nhớ được cấp phát bởi "XS_unpack_foo_tPtr".
T_PACKEDARRAY
T_PACKEDARRAY tương tự như T_PACKED. Trên thực tế, sơ đồ đánh máy "INPUT" (Perl to XSUB) là
giống hệt nhau, nhưng bản đồ kiểu "OUTPUT" chuyển một đối số bổ sung cho
Hàm "XS_pack_ $ ntype". Tham số thứ ba này cho biết số phần tử trong
đầu ra để hàm có thể xử lý các mảng C. Biến cần phải là
do người dùng khai báo và phải có tên "count_ $ ntype" trong đó $ ntype là
tên loại C chuẩn hóa như đã giải thích ở trên. Chữ ký của hàm sẽ dành cho
ví dụ ở trên và "foo_t **":
khoảng trống tĩnh
XS_pack_foo_tPtrPtr (SV * out, foo_t * in, UV count_foo_tPtrPtr);
Kiểu của tham số thứ ba là tùy ý đối với bản đồ chính tả. Nó
chỉ cần phải phù hợp với biến đã khai báo.
Tất nhiên, trừ khi bạn biết số phần tử trong mảng C "sometype **", trong
XSUB của bạn, giá trị trả về từ "foo_t ** XS_unpack_foo_tPtrPtr (...)" sẽ khó
giải mã. Vì tất cả các chi tiết đều phụ thuộc vào tác giả XS (người dùng sơ đồ đánh máy), có
một số giải pháp, không có giải pháp nào đặc biệt thanh lịch. Thường thấy nhất
giải pháp là cấp phát bộ nhớ cho N + 1 con trỏ và gán "NULL" cho (N + 1) th
để tạo điều kiện lặp lại.
Ngoài ra, ngay từ đầu, việc sử dụng một sơ đồ đánh máy tùy chỉnh cho các mục đích của bạn là
có lẽ thích hợp hơn.
T_DATAUNIT
CHƯA
T_GỌI LẠI
CHƯA
T_ARRAY
Điều này được sử dụng để chuyển đổi danh sách đối số perl thành một mảng C và để đẩy
nội dung của một mảng C vào ngăn xếp đối số perl.
Chữ ký gọi điện thông thường là
@out = array_func (@in);
Bất kỳ số lượng đối số nào cũng có thể xuất hiện trong danh sách trước mảng trừ giá trị đầu vào và
mảng đầu ra phải là phần tử cuối cùng trong danh sách.
Khi được sử dụng để chuyển một danh sách perl đến C, người viết XS phải cung cấp một hàm (được đặt tên theo
kiểu mảng nhưng với 'Ptr' được thay thế cho '*') để cấp phát bộ nhớ cần thiết cho
giữ danh sách. Một con trỏ sẽ được trả lại. Người viết XS tùy thuộc vào việc giải phóng
bộ nhớ khi thoát khỏi chức năng. Biến "ix_ $ var" được đặt thành số
các phần tử trong mảng mới.
Khi trả về mảng C cho Perl, người viết XS phải cung cấp một biến số nguyên được gọi là
"size_ $ var" chứa số phần tử trong mảng. Điều này được sử dụng để xác định
bao nhiêu phần tử sẽ được đẩy vào ngăn xếp đối số trả về. Đây không phải là
yêu cầu đầu vào vì Perl biết có bao nhiêu đối số trên ngăn xếp khi
thường xuyên được gọi. Thông thường, biến này sẽ được gọi là "size_RETVAL".
Ngoài ra, kiểu của mỗi phần tử được xác định từ kiểu của mảng. Nếu như
mảng sử dụng kiểu "intArray *" xsubpp sẽ tự động tìm ra rằng nó chứa
các biến kiểu "int" và sử dụng mục nhập sơ đồ kiểu đó để thực hiện việc sao chép từng biến
yếu tố. Tất cả các thẻ con trỏ '*' và 'Mảng' được xóa khỏi tên để xác định
kiểu con.
T_STDIO
Điều này được sử dụng để chuyển các xử lý tệp perl đến và đi từ C bằng cách sử dụng cấu trúc "FILE *".
T_INOUT
Điều này được sử dụng để chuyển các xử lý tệp perl đến và đi từ C bằng cách sử dụng cấu trúc "PerlIO *".
Tay cầm tập tin có thể được sử dụng để đọc và ghi. Điều này tương ứng với chế độ "+ <",
xem thêm T_IN và T_OUT.
Xem perliol để biết thêm thông tin về lớp trừu tượng Perl IO. Perl phải được
được xây dựng bằng "-Duseperlio".
Không có kiểm tra nào để khẳng định rằng bộ xử lý tệp được chuyển từ Perl sang C được tạo bằng
chế độ "open ()" phù hợp.
Gợi ý: Hướng dẫn perlxstut bao gồm các loại XS T_INOUT, T_IN và T_OUT một cách độc đáo.
T_IN
Tương tự như T_INOUT, nhưng chỉ có thể sử dụng bộ xử lý tệp được trả về từ C sang Perl
để đọc (chế độ "<").
T_OUT
Tương tự như T_INOUT, nhưng bộ xử lý tệp được trả về từ C đến Perl được đặt để sử dụng
mở chế độ "+>".
Sử dụng perlxstypemap trực tuyến bằng các dịch vụ onworks.net