C-DynaLib
view release on metacpan or search on metacpan
in the sub declarer's package. Second arg to C::DynaLib->new will be
passed along to DynaLoader::dl_load_file.
0.52 Sat Oct 18 18:41:42 1997
Some efforts toward portability, especially among Sparc
compilers.
0.51 Fri Oct 3 23:55:27 1997
Renamed as C::DynaLib. Fixed Makefile.PL bug that resulted
in NUL chars in DynaLib.c. Errors in loading libs, finding symbols,
and allocating callbacks are no longer fatal.
0.50 Sat Sep 27 01:35:55 1997
Much nicification and many added arg/return types. Rewrote
a lot of the guts.
0.31 Thu Aug 28 23:42 1997
Digital Unix on the Alpha is supported, at least for gcc,
thanks to help from Achim Bohnet <ach@mpe.mpg.de>. Added PTR_TYPE.
0.30 Mon Aug 11 00:58:55 1997
Added testcall configuration utility to find system
dependencies for cdecl convention. Rewrote some docs.
0.22 Wed Jul 30 01:12 1997
Renamed methods to avoid possible future keyword conflict:
declare_sub became DeclareSub, poke became Poke, etc. Added
ExtUtils::DynaLib::Struct package. Got it to work on Windows 95 with
Borland C++ (but probably not repeatably ;-) )
0.21 Sat Jul 12 02:01:12 1997
die works with callbacks (except in certain complex cases).
Added a few bits & pieces.
Sun's cc is now supported (thanks to lvirden@cas.org).
0.20 Mon Jul 7 23:42:00 1997
Support for callbacks. Major and minor bugfixes.
0.13-0.14 Nicified for CPAN.
0.12 Sun Jun 22 10:34:21 1997
Minor stuff. Renamed to ExtUtils::DynaLib.
0.11 Thu Jun 19 23:43:29 1997
Added sparc convention.
0.10 Wed Jun 18 13:31:07 EDT 1997
Makefile.PL view on Meta::CPAN
use ExtUtils::MakeMaker;
use strict;
require 5.002;
use Config;
my(@convention, $convention,
$num_callbacks, %cflags, $object, $devnull,
$conv_xs, $cbfunc_c, $cdecl_h, $postamble,
$is_gcc, $is_msvc, $is_borland, $is_dynamic,
$is_win32, $Verbose,
$stack_reserve, $stack_adjust, $stack_align,
$do_reverse);
my $Cpp; # run testcall through -E -P (might break, just for debugging)
$conv_xs = "conv.xsi";
$cbfunc_c = "cbfunc.c";
$cdecl_h = "cdecl.h";
Makefile.PL view on Meta::CPAN
*** you have to rebuild perl. Choose "y" when Configure asks, "Do
*** you wish to use dynamic loading?".
STATIC
@convention = ();
%cflags = ();
for (@ARGV) {
/^DECL=(.*)$/ and push @convention, split(",", $1);
/^CALLBACKS=(\d+)$/ and $num_callbacks = $1;
/^(-D.*)(?:\=(.*))?$/ and $cflags{$1} = $2;
/^Verbose$/i and $Verbose = 1;
/^Cpp$/i and $Cpp = 1;
/^STACK_RESERVE=(\d+)$/ and $stack_reserve = $1;
/^STACK_ADJUST=(\d+)$/ and $stack_adjust = $1;
/^STACK_ALIGN=(\d+)$/ and $stack_align = $1;
}
# Appease MakeMaker:
@ARGV = grep { !/^(DECL=|CALLBACKS=\d+$|-D.|STACK_\w+=\d+)/ } @ARGV;
Makefile.PL view on Meta::CPAN
if $Verbose;
for (@convention) {
# $cflags{"-DDYNALIB_DECL=\\\"$_\\\""} = undef;
$cflags{"-DDYNALIB_USE_$_"} = undef;
}
print "Default calling convention: $convention[0]\n"
if $Verbose;
$cflags{"-DDYNALIB_DEFAULT_CONV"} = "\\\"$convention[0]\\\"";
$num_callbacks = 4 unless defined($num_callbacks);
print "Maximum number of callbacks: $num_callbacks\n"
if $Verbose;
$cflags{"-DDYNALIB_NUM_CALLBACKS"} = $num_callbacks;
my $defines = "\nDEFINE =";
for (sort keys %cflags) {
$defines .= " $_";
$defines .= "=$cflags{$_}" if defined $cflags{$_};
}
$postamble .= $defines;
print "Additional definitions: $defines\n"
if $Verbose and scalar(keys %cflags)>1;
write_conv();
Makefile.PL view on Meta::CPAN
print "Writing $cbfunc_c\n";
print FUNCS <<FUNCS;
/*
* $cbfunc_c generated by $0. Don't edit this file, edit $0.
*/
FUNCS
#
# The callback functions.
#
for $i (0 .. $num_callbacks - 1) {
print FUNCS <<FUNCS;
static long
#ifdef I_STDARG
_cb_func$i(void * first, ...)
#else
_cb_func$i(first, va_alist)
void * first;
va_dcl
#endif
Makefile.PL view on Meta::CPAN
va_end(ap);
return result;
}
FUNCS
}
#
# Array of callback entry pointers.
#
print FUNCS "\nstatic const cb_callback cb_arr[DYNALIB_NUM_CALLBACKS] = {\n";
for $i (0 .. $num_callbacks - 1) {
print FUNCS "\t_cb_func$i,\n";
}
print FUNCS "};\n";
}
sub parse_perl_types
{
unless (eval "require Convert::Binary::C;") {
print "Warning: Convert::Binary::C not installed. PerlTypes not generated.\n";
return;
lib/C/DynaLib.pm view on Meta::CPAN
my $self = [];
my ($index, $coderef);
my ($codeptr, $ret_type, $arg_type, @arg_type, $func);
my $i;
for ($index = 0; $index <= $#{$Config}; $index++) {
($codeptr, $ret_type, $arg_type, $func)
= unpack(CONFIG_TEMPLATE, $Config->[$index]);
last unless $codeptr;
}
if ($index > $#{$Config}) {
carp "Limit of ", scalar(@$Config), " callbacks exceeded";
return undef;
}
($coderef, $ret_type, @arg_type) = @_;
$ret_type =~ /^$GoodRet$/o
or croak "Invalid callback return type: '$ret_type'";
! @arg_type || $arg_type[0] =~ /^$GoodFirst$/o
or croak "Invalid callback first argument type: '$arg_type[0]'";
for $i (@arg_type[1..$#arg_type]) {
$i =~ /^$GoodArg$/o
lib/C/DynaLib.pm view on Meta::CPAN
through it results in a call to the C function. See L<perlref(1)> on
how to use code references.
=head2 C::DynaLib::Callback( \&some_sub, $ret_type, @arg_types )
Using callback routines
Some C functions expect a pointer to another C function as an
argument. The library code that receives the pointer may use it to
call an application function at a later time. Such functions are
called I<callbacks>.
This module allows you to use a Perl sub as a C callback, subject to
certain restrictions. There is a hard-coded maximum number of
callbacks that can be active at any given time. The default (4) may
be changed by specifying C<CALLBACKS=number> on the F<Makefile.PL>
command line.
A callback's argument and return types are specified using C<pack>
codes, as described above for library functions. Currently, the
return value must be interpretable as type C<int> or C<void>, so the
only valid codes are C<"i">, C<"I">, and C<"">. There are also
restrictions on the permissible argument types, especially for the
first argument position. These limitations are considered bugs to be
fixed someday.
lib/C/DynaLib.pm view on Meta::CPAN
use C::DynaLib;
$libc = new C::DynaLib("-lc");
$strncmp = $libc->DeclareSub("strncmp", "i", "p", "p", "I");
$string1 = "foobar";
$string2 = "foolish";
$result = &{$strncmp}($string1, $string2, 3); # $result is 0
$result = &{$strncmp}($string1, $string2, 4); # $result is -1
The files F<test.pl> and F<README.win32> contain examples using
callbacks.
=head1 CALLING CONVENTIONS
This section is intended for anyone who is interested in debugging or
extending this module. You probably don't need to read it just to
I<use> the module.
=head2 The problem
The hardest thing about writing this module is to accommodate the
lib/C/DynaLib.pm view on Meta::CPAN
&$strncmp("foo", "bar", 3);
To work around this problem, one must assign the value to a variable
and pass the variable in its place, as in
&$strncmp($dummy1 = "foo", $dummy2 = "bar", 3);
=head2 Callbacks
Only a certain number of callbacks can exist at a time. Callbacks can
mess up the message produced by C<die> in the presence of nested
C<eval>s. The Callback code uses global data, and is consequently not
thread-safe.
=head2 Miscellaneous Bugs
There are restrictions on what C data types may be used. Using
argument types of unusual size may have nasty results. The techniques
used to pass values to and from C functions are generally hackish and
nonstandard. Assembly code would be more complete. Makefile.PL does
"P$ptr_len", "P$ptr_len");
my $qsort = $libc->DeclareSub("qsort", "",
"P", "I", "I", PTR_TYPE);
&$qsort($array, scalar(@list), length($array) / @list, $callback->Ptr());
my @expected = sort { length($a) <=> length($b) } @list;
my @got = unpack("p*", $array);
ok("[@got]" eq "[@expected]"); #7
# Hey! We've got callbacks. We've got a way to call them.
# Who needs libraries?
undef $callback;
$callback = new C::DynaLib::Callback
(sub {
$_[0] + 10*$_[1] + 100*$_[2];
}, "i", "i", "p", "i");
my $sub = DeclareSub($callback->Ptr(), "i", "i", "p", "i");
my $got = &$sub(1, $tmp = 7, 3.14);
my $expected = 371;
( run in 0.488 second using v1.01-cache-2.11-cpan-9b1e4054eb1 )