1Wx::Loader(3) User Contributed Perl Documentation Wx::Loader(3)
2
3
4
6 Wx::Loader - using custom dll loaders with Wx
7
9 #---------------------------------------
10 # For Packagers
11 #---------------------------------------
12
13 # the order of these use()s is important
14 use MyCustomWxLoader;
15 use Wx;
16
17 or .....
18
19 use threads;
20 use threads::shared;
21 use MyCustomLoader;
22 use Wx;
23
24 or - Wx::Perl::Splashfast special case
25
26 use MyCustomWxLoader;
27 use Wx::Perl::SplashFast ("./logo.jpg",5000);
28 use Wx;
29
30 ............. meanwhile in MyCustomWxLoader.pm
31
32 package MyCustomWxLoader;
33 require Wx::Mini;
34 our @ISA = qw( Wx::Loader::Standard );
35
36 $Wx::wx_binary_loader = __PACKAGE__;
37 ...... or
38 $Wx::wx_binary_loader = __PACKAGE__->new;
39
40 #-----------------------------------------
41 # For binary distributions
42 #-----------------------------------------
43
44 # Provide a custom Wx::Loader::Custom
45 # to be loaded by Wx::Mini
46
47 package Wx::Loader::Custom
48 our @ISA = qw( Wx::Loader::Standard );
49
50 # be polite if another loader is already in place
51
52 $Wx::wx_binary_loader = __PACKAGE__ if !$Wx::wx_binary_loader;
53 ...... or
54 $Wx::wx_binary_loader = __PACKAGE__->new() if !$Wx::wx_binary_loader;
55
57 If you are providing binary distributions of Wx or packaging Wx
58 applications to run on machines without Perl (PAR, PerlApp),you may
59 need to override dll loading methods. Providing a custom
60 wx_binary_loader package allows you to do this.
61
63 A binary distribution my provide alternative sources and loading
64 methods for the wxWidgets dlls. It achieves this by providing a
65 Wx::Loader::Custom module in the distribution
66
67 package Wx::Loader::Custom
68 our @ISA = qw( Wx::Loader::Standard );
69
70 # be polite if another loader is already in place
71
72 $Wx::wx_binary_loader = __PACKAGE__ if !$Wx::wx_binary_loader;
73 ...... or
74 $Wx::wx_binary_loader = __PACKAGE__->new() if !$Wx::wx_binary_loader;
75
76 # remember that Wx.pm has not necessarily been loaded so only
77 # Wx::Mini is available
78
80 Applications that package perl scripts to run on machines without
81 Perl (PAR, PerlApp etc) can override dll loading methods if necessary
82 by loading a custom package before wx
83
84 package MyCustomWxLoader;
85 require Wx::Mini;
86 our @ISA = qw( Wx::Loader::Standard );
87
88 $Wx::wx_binary_loader = __PACKAGE__;
89 ...... or
90 $Wx::wx_binary_loader = __PACKAGE__->new;
91
92 # remember that Wx.pm has not necessarily been loaded so only
93 # Wx::Mini is available
94
96 The following methods may be provided by custom loaders to override the
97 default behaviour
98
99 loader_info
100 should return an information string about the loader and MUST be provided.
101 The default loader has
102
103 sub loader_info { 'Standard Distribution'; }
104
105 so any custom loader should return something different
106
107 e.g.
108
109 sub loader_info { "Mark's Broken Distribution - it's all my fault"; }
110
111 set_binary_path
112 allows setting a custom path for the wxWidgets libraries.
113
114 sub set_binary_path {
115 my $class_or_object = shift;
116
117 ... work out binary path
118
119 return $newbinarypath; # method MUST return a path
120 }
121
122 load_dll
123 Is called to load wxWidgets plugin dlls using a key for the $Wx::dlls hash
124 ( see Wx::Mini )
125
126 sub load_dll {
127 my ($class_or_object, $dllkey) = @_;
128 ..... load dll - or maybe not
129 }
130
131 the default loader does nothing - dependencies are loaded automatically
132 and determined by the standard methods of the os:
133
134 an example of pre loading a known dependency
135
136 sub load_dll {
137 return if $^O !~ /^(mswin|linux)/i;
138 local $ENV{PATH} = $Wx::wx_path . ';' . $ENV{PATH} if $Wx::wx_path;
139 return unless exists $Wx::dlls->{$_[1]} && $Wx::dlls->{$_[1]};
140 my $dll = $Wx::dlls->{$_[1]};
141 $dll = $Wx::wx_path . '/' . $dll if $Wx::wx_path;
142 Wx::_load_plugin( $dll );
143 }
144
145 unload_dll
146 Is called ONCE from within an END block
147 A custom loader may choose, for example to unload any dlls it has loaded
148
149 sub unload_dll {
150 my $class_or_object = shift;
151
152 ... carry out END actions
153 }
154
155 The default unload_dll is a noop ( sub unload_dll {} )
156
157 external_set_load
158 A deprecated method of replacing the load function for plugins
159 A custom loader may override this to prevent a legacy loader replacing
160 the loading methods.
161
162 external_set_unload
163 A deprecated method of replacing the unload function for plugins
164 A custom loader may override this to prevent a legacy loader replacing
165 the unloading methods.
166
167 boot_overload
168 For binary distributions and packaged applications, normal shared
169 library loading semantics may not work. A custom loader may provide
170 this method to use in place of, or to supplement the standard XS load
171 of Wx.dll (Wx.so).
172
173 The method MUST return true or false, depending on whether it has
174 loaded Wx.dll (Wx.so).
175
176 For example, to load the core wxWidgets dlls before Wx is loaded
177
178 sub boot_overload {
179 shift;
180 require DynaLoader;
181 for my $dll ( qw( base core adv ) ) {
182 next unless exists $Wx::dlls->{$dll} && $Wx::dlls->{$dll};
183 my $file = ( $Wx::wx_path ) ? $Wx::wx_path . '/' . $Wx::dlls->{$dll} : $Wx::dlls->{$dll};
184 my $libref = DynaLoader::dl_load_file($file, 0);
185 push(@DynaLoader::dl_librefs,$libref) if $libref;
186
187 # Dynaloader should take care of unloading
188
189 }
190
191 #------------ IMPORTANT ----------
192 return 0; # we have not loaded Wx
193 #---------------------------------
194 }
195
196
197 Some packagers extract dlls at runtime, and then may attempt to remove them
198 at application close. This may fail for Wx. For example, on MSWin the directory
199 cleanup fails whilst on Linux the application will seg-fault on exit.
200 Packagers may avoid this by loading Wx.dll( Wx.so) from a non standard location
201 ( perhaps a separate binary distribution of wx dlls ) that is not removed at
202 application exit.
203
204 For example
205
206 sub boot_overload {
207 my $class = shift
208 require DynaLoader;
209 for my $dll ( qw( base core adv ) ) {
210 next unless exists $Wx::dlls->{$dll} && $Wx::dlls->{$dll};
211 my $file = ( $Wx::wx_path ) ? $Wx::wx_path . '/' . $Wx::dlls->{$dll} : $Wx::dlls->{$dll};
212 my $libref = DynaLoader::dl_load_file($file, 0);
213 push(@DynaLoader::dl_librefs,$libref) if $libref;
214
215 # Dynaloader should take care of unloading
216
217 }
218
219 package
220 DynaLoader;
221
222 my $file = $class->get_the_location_to_wx_xs_module;
223
224 #------------------------------------------
225 # From XSLoader
226 #------------------------------------------
227
228 my $module = 'Wx';
229
230 my $boots = "$module\::bootstrap";
231 my $bootname = "boot_$module";
232 $bootname =~ s/\W/_/g;
233 @DynaLoader::dl_require_symbols = ($bootname);
234 my $boot_symbol_ref;
235
236 my $libref = dl_load_file($file, 0) or do {
237 require Carp;
238 Carp::croak("Can't load '$file' for module $module: " . dl_error());
239 };
240 push(@DynaLoader::dl_librefs,$libref); # record loaded object
241
242 my @unresolved = dl_undef_symbols();
243 if (@unresolved) {
244 require Carp;
245 Carp::carp("Undefined symbols present after loading $file: @unresolved\n");
246 }
247
248 $boot_symbol_ref = dl_find_symbol($libref, $bootname) or do {
249 require Carp;
250 Carp::croak("Can't find '$bootname' symbol in $file\n");
251 };
252
253 push(@DynaLoader::dl_modules, $module); # record loaded module
254
255 my $xs = dl_install_xsub($boots, $boot_symbol_ref, $file);
256
257 push(@DynaLoader::dl_shared_objects, $file); # record files loaded
258
259 #------------ IMPORTANT ----------
260 return 1; # we have loaded Wx
261 #---------------------------------
262 }
263
265 ################################################
266 # Custom loader for Wx distribution from
267 # http://www.wxperl.co.uk/repository
268 #
269 ################################################
270
271 package Wx::Loader::Custom;
272 use strict;
273 use warnings;
274
275 our @ISA = qw( Wx::Loader::Standard );
276
277 $Wx::wx_binary_loader = __PACKAGE__ if !$Wx::wx_binary_loader;
278
279 sub loader_info { 'Linux PPM Distribution from http://www.wxperl.co.uk/repository'; }
280
281 sub boot_overload {
282 shift;
283 require DynaLoader;
284 for my $dll ( qw( base core adv ) ) {
285 next unless exists $Wx::dlls->{$dll} && $Wx::dlls->{$dll};
286 my $file = ( $Wx::wx_path ) ? $Wx::wx_path . '/' . $Wx::dlls->{$dll} : $Wx::dlls->{$dll};
287 my $libref = DynaLoader::dl_load_file($file, 0);
288 push(@DynaLoader::dl_librefs,$libref) if $libref;
289
290 # Dynaloader should take care of unloading
291 }
292 return 0;
293 }
294
295 # Allow legacy packaging call to override our load method
296
297 my( $load_fun ) = ( \&_load_dll );
298
299 sub _load_dll {
300 return unless exists $Wx::dlls->{$_[0]} && $Wx::dlls->{$_[0]};
301 my $dll = $Wx::dlls->{$_[0]};
302 $dll = $Wx::wx_path . '/' . $dll if $Wx::wx_path;
303 return Wx::_load_plugin( $dll );
304 }
305
306 sub external_set_load { $load_fun = $_[1] }
307
308 sub load_dll {
309 shift;
310 goto &$load_fun;
311 }
312
313
314
315perl v5.34.0 2022-01-21 Wx::Loader(3)