1package FFI::Platypus::DL;
2
3use strict;
4use warnings;
5use 5.008004;
6use Exporter qw( import );
7
8require FFI::Platypus;
9our @EXPORT = qw( dlopen dlerror dlsym dlclose );
10push @EXPORT, grep /RTLD_/, keys %FFI::Platypus::DL::;
11
12# ABSTRACT: Slightly non-portable interface to libdl
13our $VERSION = '1.56'; # VERSION
14
15
161;
17
18__END__
19
20=pod
21
22=encoding UTF-8
23
24=head1 NAME
25
26FFI::Platypus::DL - Slightly non-portable interface to libdl
27
28=head1 VERSION
29
30version 1.56
31
32=head1 SYNOPSIS
33
34 use FFI::Platypus 1.00;
35 use FFI::Platypus::DL;
36
37 my $handle = dlopen("./libfoo.so", RTLD_PLATYPUS_DEFAULT);
38 my $address = dlsym($handle, "my_function_named_foo");
39 my $ffi = FFI::Platypus->new( api => 1 );
40 $ffi->function($address => [] => 'void')->call;
41 dlclose($handle);
42
43=head1 DESCRIPTION
44
45This module provides an interface to libdl, the dynamic loader on UNIX.  The underlying interface
46has always been used by L<FFI::Platypus>, but it wasn't a public interface until version 0.52.  The
47name was changed with that version when it became a public interface, so be sure to specify that
48version if you are going to use it.
49
50It is somewhat non-portable for these reasons:
51
52=over 4
53
54=item GNU extensions
55
56It provides some GNU extensions to platforms such as Linux that support them.
57
58=item Windows
59
60It provides an emulation layer on Windows.  The emulation layer only supports C<RTLD_PLATYPUS_DEFAULT>
61as a flag.  The emulation layer emulates the convention described below of passing C<undef> as
62the dynamic library name to mean, use the currently running executable.  I've used it without
63any problems for years, but Windows is not my main development platform.
64
65=back
66
67=head1 FUNCTIONS
68
69=head2 dlopen
70
71 my $handle = dlopen($filename, $flags);
72
73This opens a dynamic library in the context of the dynamic loader.  C<$filename> is the full or
74relative path to a dynamic library (usually a C<.so> on Linux and some other UNIXen, a C<.dll> on
75Windows and a C<.dylib> on OS X).  C<$flags> are flags that can be used to alter the behavior
76of the library and the symbols it contains.  The return value is an opaque pointer or C<$handle>
77which can be used to look up symbols with C<dlsym>.  The handle should be closed with C<dlclose>
78when you are done with it.
79
80By convention if you pass in C<undef> for the filename, the currently loaded executable will be
81used instead of a separate dynamic library.  This is the easiest and most portable way to find
82the address of symbols in the standard C library.  This convention is baked into most UNIXen,
83but this capability is emulated in Windows which doesn't come with the capability out of the box.
84
85If there is an error in opening the library then C<undef> will be returned and the diagnostic
86for the failure can be retrieved with C<dlerror> as described below.
87
88Not all flags are supported on all platforms.  You can test if a flag is available using can:
89
90 if(FFI::Platypus::DL->can('RTLD_LAZY'))
91 {
92   ...
93 }
94
95Typically where flags are not mutually exclusive, they can be or'd together:
96
97 my $handle = dlopen("libfoo.so", RTLD_LAZY | RTLD_GLOBAL);
98
99Check your operating system documentation for detailed descriptions of these flags.
100
101=over 4
102
103=item RTLD_PLATYPUS_DEFAULT
104
105This is the L<FFI::Platypus> default for C<dlopen> (NOTE: NOT the libdl default).  This is the only
106flag supported on Windows.  For historical reasons, this is usually C<RTLD_LAZY> on Unix and C<0> on
107Windows.
108
109=item RTLD_LAZY
110
111Perform lazy binding.
112
113=item RTLD_NOW
114
115Resolve all symbols before returning from C<dlopen>.  Error if all symbols cannot resolve.
116
117=item RTLD_GLOBAL
118
119Symbols are shared.
120
121=item RTLD_LOCAL
122
123Symbols are NOT shared.
124
125=item RTLD_NODELETE
126
127glibc 2.2 extension.
128
129=item RTLD_NOLOAD
130
131glibc 2.2 extension.
132
133=item RTLD_DEEPBIND
134
135glibc 2.3.4 extension.
136
137=back
138
139=head2 dlsym
140
141 my $opaque = dlsym($handle, $symbol);
142
143This looks up the given C<$symbol> in the library pointed to by C<$handle>.  If the symbol is found,
144the address for that symbol is returned as an opaque pointer.  This pointer can be passed into
145the L<FFI::Platypus> C<function> and C<attach> methods instead of a function name.
146
147If the symbol cannot be found then C<undef> will be returned and the diagnostic for the failure can
148be retrieved with C<dlerror> as described below.
149
150=head2 dlclose
151
152 my $status = dlclose($handle);
153
154On success, C<dlclose> returns 0; on error, it returns a nonzero value, and the diagnostic for the
155failure can be retrieved with C<dlerror> as described below.
156
157=head2 dlerror
158
159 my $error_string = dlerror;
160
161Returns the human readable diagnostic for the reason for the failure for the most recent C<dl>
162prefixed function call.
163
164=head1 CAVEATS
165
166Some flags for C<dlopen> are not portable.  This module may not be supported platforms added to
167L<FFI::Platypus> in the future.  It does work as far as I know on all of the currently supported
168platforms.
169
170=head1 SEE ALSO
171
172=over 4
173
174=item L<FFI::Platypus>
175
176=back
177
178=head1 AUTHOR
179
180Author: Graham Ollis E<lt>plicease@cpan.orgE<gt>
181
182Contributors:
183
184Bakkiaraj Murugesan (bakkiaraj)
185
186Dylan Cali (calid)
187
188pipcet
189
190Zaki Mughal (zmughal)
191
192Fitz Elliott (felliott)
193
194Vickenty Fesunov (vyf)
195
196Gregor Herrmann (gregoa)
197
198Shlomi Fish (shlomif)
199
200Damyan Ivanov
201
202Ilya Pavlov (Ilya33)
203
204Petr Písař (ppisar)
205
206Mohammad S Anwar (MANWAR)
207
208Håkon Hægland (hakonhagland, HAKONH)
209
210Meredith (merrilymeredith, MHOWARD)
211
212Diab Jerius (DJERIUS)
213
214Eric Brine (IKEGAMI)
215
216szTheory
217
218José Joaquín Atria (JJATRIA)
219
220Pete Houston (openstrike, HOUSTON)
221
222=head1 COPYRIGHT AND LICENSE
223
224This software is copyright (c) 2015,2016,2017,2018,2019,2020 by Graham Ollis.
225
226This is free software; you can redistribute it and/or modify it under
227the same terms as the Perl 5 programming language system itself.
228
229=cut
230