Codebase list libffi-platypus-perl / a8d1f13
add curl example Graham Ollis authored 1 year, 6 months ago Graham✈️✈️ committed 1 year, 6 months ago
7 changed file(s) with 168 addition(s) and 18 deletion(s). Raw diff Collapse all Expand all
00 Revision history for {{$dist->name}}
11
22 {{$NEXT}}
3 - Documentation improvements (gh#372, gh#381, gh#382, gh#383, gh#384)
3 - Documentation improvements (gh#372, gh#380, gh#381, gh#382, gh#383, gh#384,
4 gh#386)
45
56 2.03 2022-10-27 21:19:06 -0600
67 - Add hook for detecting bundled Zig project. You will need to install
17031703 use FFI::Platypus::Buffer qw( scalar_to_buffer window );
17041704
17051705 my $endpoint = "ipc://zmq-ffi-$$";
1706 my $ffi = FFI::Platypus->new( api => 2 );
1707
1708 $ffi->lib(undef); # for puts
1709 $ffi->attach(puts => ['string'] => 'int');
1710
1711 $ffi->lib(find_lib_or_die lib => 'zmq');
1706 my $ffi = FFI::Platypus->new(
1707 api => 2,
1708 lib => find_lib_or_die lib => 'zmq',
1709 );
1710
17121711 $ffi->attach(zmq_version => ['int*', 'int*', 'int*'] => 'void');
17131712
17141713 my($major,$minor,$patch);
17151714 zmq_version(\$major, \$minor, \$patch);
1716 puts("libzmq version $major.$minor.$patch");
1715 print "libzmq version $major.$minor.$patch\n";
17171716 die "this script only works with libzmq 3 or better" unless $major >= 3;
17181717
17191718 $ffi->type('opaque' => 'zmq_context');
18101809 # the ArchiveWrite class that could be used for writing archive formats
18111810 # supported by libarchive
18121811
1813 my $ffi = FFI::Platypus->new( api => 2 );
1814 $ffi->lib(find_lib_or_die lib => 'archive');
1812 my $ffi = FFI::Platypus->new(
1813 api => 2,
1814 lib => find_lib_or_die(lib => 'archive'),
1815 );
18151816 $ffi->type('object(Archive)' => 'archive_t');
18161817 $ffi->type('object(ArchiveRead)' => 'archive_read_t');
18171818 $ffi->type('object(ArchiveWrite)' => 'archive_write_t');
20172018 of `opaque` (the latter being the default for the `object` type).
20182019 Mainly just for demonstration since Perl has much better IO libraries,
20192020 but now we have an OO interface to the Unix IO functions.
2021
2022 ## Varadic Functions (with libcurl)
2023
2024 ### C API
2025
2026 - [curl\_easy\_init](https://curl.se/libcurl/c/curl_easy_init.html)
2027 - [curl\_easy\_setopt](https://curl.se/libcurl/c/curl_easy_setopt.html)
2028 - [curl\_easy\_perform](https://curl.se/libcurl/c/curl_easy_perform.html)
2029 - [curl\_easy\_cleanup](https://curl.se/libcurl/c/curl_easy_cleanup.html)
2030
2031 ### Perl Source
2032
2033 ```perl
2034 use FFI::Platypus 2.00;
2035 use FFI::CheckLib qw( find_lib_or_die );
2036 use constant CURLOPT_URL => 10002;
2037
2038 my $ffi = FFI::Platypus->new(
2039 api => 2,
2040 lib => find_lib_or_die(lib => 'curl'),
2041 );
2042
2043 # https://curl.se/libcurl/c/curl_easy_init.html
2044 my $curl_handle = $ffi->function( 'curl_easy_init' => [] => 'opaque' )
2045 ->call;
2046
2047 # https://curl.se/libcurl/c/curl_easy_setopt.html
2048 $ffi->function( 'curl_easy_setopt' => ['opaque', 'enum' ] => ['string'] )
2049 ->call($curl_handle, CURLOPT_URL, "https://pl.atypus.org" );
2050
2051 # https://curl.se/libcurl/c/curl_easy_perform.html
2052 $ffi->function( 'curl_easy_perform' => ['opaque' ] => 'enum' )
2053 ->call($curl_handle);
2054
2055 # https://curl.se/libcurl/c/curl_easy_cleanup.html
2056 $ffi->function( 'curl_easy_cleanup' => ['opaque' ] )
2057 ->call($curl_handle);
2058 ```
2059
2060 ### Execute
2061
2062 ```
2063 $ perl curl.pl
2064 <!doctype html>
2065 <html lang="en">
2066 <head>
2067 <meta charset="utf-8" />
2068 <title>pl.atypus.org - Home for the Perl Platypus Project</title>
2069 ...
2070 ```
2071
2072 ### Discussion
2073
2074 The `libcurl` library makes extensive use of "varadic" functions.
2075
2076 The C programming language and ABI have the concept of "varadic" functions
2077 that can take a variable number and variable type of arguments. Assuming
2078 you have a `libffi` that supports it (and most modern systems should),
2079 then you can create bindings to a varadic function by providing two sets
2080 of array references, one for the fixed arguments (for reasons, C varadic
2081 functions must have at least one) and one for variable arguments. In
2082 this example we call `curl_easy_setopt` as a varadic function.
2083
2084 For functions that have a large or infinite number of possible signatures
2085 it may be impracticable or impossible to attach them all. You can instead
2086 do as we did in this example, create a function object using the
2087 [function method](#function) and call it immediately. This is not as
2088 performant either when you create or call as using the [attach method](#attach),
2089 but in some cases the performance penalty may be worth it or unavoidable.
20202090
20212091 ## bundle your own code
20222092
159159 - NULLs
160160 - XORd
161161 - decrypted
162 - varadic
163 - libcurl
164 - performant
162165
163166 pod_coverage:
164167 skip: 0
77 # the ArchiveWrite class that could be used for writing archive formats
88 # supported by libarchive
99
10 my $ffi = FFI::Platypus->new( api => 2 );
11 $ffi->lib(find_lib_or_die lib => 'archive');
10 my $ffi = FFI::Platypus->new(
11 api => 2,
12 lib => find_lib_or_die(lib => 'archive'),
13 );
1214 $ffi->type('object(Archive)' => 'archive_t');
1315 $ffi->type('object(ArchiveRead)' => 'archive_read_t');
1416 $ffi->type('object(ArchiveWrite)' => 'archive_write_t');
0 use strict;
1 use warnings;
2 use FFI::Platypus 2.00;
3 use FFI::CheckLib qw( find_lib_or_die );
4 use constant CURLOPT_URL => 10002;
5
6 my $ffi = FFI::Platypus->new(
7 api => 2,
8 lib => find_lib_or_die(lib => 'curl'),
9 );
10
11 # https://curl.se/libcurl/c/curl_easy_init.html
12 my $curl_handle = $ffi->function( 'curl_easy_init' => [] => 'opaque' )
13 ->call;
14
15 # https://curl.se/libcurl/c/curl_easy_setopt.html
16 $ffi->function( 'curl_easy_setopt' => ['opaque', 'enum' ] => ['string'] )
17 ->call($curl_handle, CURLOPT_URL, "https://pl.atypus.org" );
18
19 # https://curl.se/libcurl/c/curl_easy_perform.html
20 $ffi->function( 'curl_easy_perform' => ['opaque' ] => 'enum' )
21 ->call($curl_handle);
22
23 # https://curl.se/libcurl/c/curl_easy_cleanup.html
24 $ffi->function( 'curl_easy_cleanup' => ['opaque' ] )
25 ->call($curl_handle);
99 use FFI::Platypus::Buffer qw( scalar_to_buffer window );
1010
1111 my $endpoint = "ipc://zmq-ffi-$$";
12 my $ffi = FFI::Platypus->new( api => 2 );
12 my $ffi = FFI::Platypus->new(
13 api => 2,
14 lib => find_lib_or_die lib => 'zmq',
15 );
1316
14 $ffi->lib(undef); # for puts
15 $ffi->attach(puts => ['string'] => 'int');
16
17 $ffi->lib(find_lib_or_die lib => 'zmq');
1817 $ffi->attach(zmq_version => ['int*', 'int*', 'int*'] => 'void');
1918
2019 my($major,$minor,$patch);
2120 zmq_version(\$major, \$minor, \$patch);
22 puts("libzmq version $major.$minor.$patch");
21 print "libzmq version $major.$minor.$patch\n";
2322 die "this script only works with libzmq 3 or better" unless $major >= 3;
2423
2524 $ffi->type('opaque' => 'zmq_context');
19251925 Mainly just for demonstration since Perl has much better IO libraries,
19261926 but now we have an OO interface to the Unix IO functions.
19271927
1928 =head2 Varadic Functions (with libcurl)
1929
1930 =head3 C API
1931
1932 =over 4
1933
1934 =item L<curl_easy_init|https://curl.se/libcurl/c/curl_easy_init.html>
1935
1936 =item L<curl_easy_setopt|https://curl.se/libcurl/c/curl_easy_setopt.html>
1937
1938 =item L<curl_easy_perform|https://curl.se/libcurl/c/curl_easy_perform.html>
1939
1940 =item L<curl_easy_cleanup|https://curl.se/libcurl/c/curl_easy_cleanup.html>
1941
1942 =back
1943
1944 =head3 Perl Source
1945
1946 # EXAMPLE: examples/curl.pl
1947
1948 =head3 Execute
1949
1950 $ perl curl.pl
1951 <!doctype html>
1952 <html lang="en">
1953 <head>
1954 <meta charset="utf-8" />
1955 <title>pl.atypus.org - Home for the Perl Platypus Project</title>
1956 ...
1957
1958 =head3 Discussion
1959
1960 The C<libcurl> library makes extensive use of "varadic" functions.
1961
1962 The C programming language and ABI have the concept of "varadic" functions
1963 that can take a variable number and variable type of arguments. Assuming
1964 you have a C<libffi> that supports it (and most modern systems should),
1965 then you can create bindings to a varadic function by providing two sets
1966 of array references, one for the fixed arguments (for reasons, C varadic
1967 functions must have at least one) and one for variable arguments. In
1968 this example we call C<curl_easy_setopt> as a varadic function.
1969
1970 For functions that have a large or infinite number of possible signatures
1971 it may be impracticable or impossible to attach them all. You can instead
1972 do as we did in this example, create a function object using the
1973 L<function method|/function> and call it immediately. This is not as
1974 performant either when you create or call as using the L<attach method|/attach>,
1975 but in some cases the performance penalty may be worth it or unavoidable.
1976
19281977 =head2 bundle your own code
19291978
19301979 C<ffi/foo.c>: