C-DynaLib

 view release on metacpan or  search on metacpan

Changes  view on Meta::CPAN

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

t/01test.t  view on Meta::CPAN

                                          "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 )