.\" Automatically generated by Pod::Man 4.14 (Pod::Simple 3.43) .\" .\" Standard preamble: .\" ======================================================================== .de Sp \" Vertical space (when we can't use .PP) .if t .sp .5v .if n .sp .. .de Vb \" Begin verbatim text .ft CW .nf .ne \\$1 .. .de Ve \" End verbatim text .ft R .fi .. .\" Set up some character translations and predefined strings. \*(-- will .\" give an unbreakable dash, \*(PI will give pi, \*(L" will give a left .\" double quote, and \*(R" will give a right double quote. \*(C+ will .\" give a nicer C++. Capital omega is used to do unbreakable dashes and .\" therefore won't be available. \*(C` and \*(C' expand to `' in nroff, .\" nothing in troff, for use with C<>. .tr \(*W- .ds C+ C\v'-.1v'\h'-1p'\s-2+\h'-1p'+\s0\v'.1v'\h'-1p' .ie n \{\ . ds -- \(*W- . ds PI pi . if (\n(.H=4u)&(1m=24u) .ds -- \(*W\h'-12u'\(*W\h'-12u'-\" diablo 10 pitch . if (\n(.H=4u)&(1m=20u) .ds -- \(*W\h'-12u'\(*W\h'-8u'-\" diablo 12 pitch . ds L" "" . ds R" "" . ds C` "" . ds C' "" 'br\} .el\{\ . ds -- \|\(em\| . ds PI \(*p . ds L" `` . ds R" '' . ds C` . ds C' 'br\} .\" .\" Escape single quotes in literal strings from groff's Unicode transform. .ie \n(.g .ds Aq \(aq .el .ds Aq ' .\" .\" If the F register is >0, we'll generate index entries on stderr for .\" titles (.TH), headers (.SH), subsections (.SS), items (.Ip), and index .\" entries marked with X<> in POD. Of course, you'll have to process the .\" output yourself in some meaningful fashion. .\" .\" Avoid warning from groff about undefined register 'F'. .de IX .. .nr rF 0 .if \n(.g .if rF .nr rF 1 .if (\n(rF:(\n(.g==0)) \{\ . if \nF \{\ . de IX . tm Index:\\$1\t\\n%\t"\\$2" .. . if !\nF==2 \{\ . nr % 0 . nr F 2 . \} . \} .\} .rr rF .\" ======================================================================== .\" .IX Title "CallExt 3pm" .TH CallExt 3pm "2023-06-17" "perl v5.36.0" "User Contributed Perl Documentation" .\" For nroff, turn off justification. Always turn off hyphenation; it makes .\" way too many mistakes in technical documents. .if n .ad l .nh .SH "NAME" PDL::CallExt \- call functions in external shared libraries .SH "SYNOPSIS" .IX Header "SYNOPSIS" .Vb 2 \& use PDL::CallExt; \& callext(\*(Aqfile.so\*(Aq, \*(Aqfoofunc\*(Aq, $x, $y); # pass ndarrays to foofunc() \& \& % perl \-MPDL::CallExt \-e callext_cc file.c .Ve .SH "DESCRIPTION" .IX Header "DESCRIPTION" \&\fBcallext()\fR loads in a shareable object (i.e. compiled code) using Perl's dynamic loader, calls the named function and passes a list of ndarray arguments to it. .PP It provides a reasonably portable way of doing this, including compiling the code with the right flags, though it requires simple perl and C wrapper routines to be written. You may prefer to use \s-1PP,\s0 which is much more portable. See \s-1PDL::PP\s0. You should definitely use the latter for a 'proper' \s-1PDL\s0 module, or if you run in to the limitations of this module. .SH "API" .IX Header "API" \&\fBcallext_cc()\fR allows one to compile the shared objects using Perl's knowledge of compiler flags. .PP The named function (e.g. 'foofunc') must take a list of ndarray structures as arguments, there is now way of doing portable general argument construction hence this limitation. .PP In detail the code in the original file.c would look like this: .PP .Vb 3 \& #include "pdlsimple.h" /* Declare simple ndarray structs \- note this .h file \& contains NO perl/PDL dependencies so can be used \& standalone */ \& \& int foofunc(int nargs, pdlsimple **args); /* foofunc prototype */ .Ve .PP i.e. \fBfoofunc()\fR takes an array of pointers to pdlsimple structs. The use is similar to that of \f(CW\*(C`main(int nargs, char **argv)\*(C'\fR in \s-1UNIX C\s0 applications. .PP pdlsimple.h defines a simple N\-dimensional data structure which looks like this: .PP .Vb 7 \& struct pdlsimple { \& int datatype; /* whether byte/int/float etc. */ \& void *data; /* Generic pointer to the data block */ \& PDL_Indx nvals; /* Number of data values */ \& PDL_Indx *dims; /* Array of data dimensions */ \& PDL_Indx ndims; /* Number of data dimensions */ \& }; .Ve .PP (PDL_Indx is 32\- or 64\-bit depending on architecture and is defined in pdlsimple.h) .PP This is a simplification of the internal representation of ndarrays in \s-1PDL\s0 which is more complicated because of broadcasting, dataflow, etc. It will usually be found somewhere like /usr/local/lib/perl5/site_perl/PDL/pdlsimple.h .PP Thus to actually use this to call real functions one would need to write a wrapper. e.g. to call a 2D image processing routine: .PP .Vb 1 \& void myimage_processer(double* image, int nx, int ny); \& \& int foofunc(int nargs, pdlsimple **args) { \& pdlsimple* image = pdlsimple[0]; \& myimage_processer( image\->data, *(image\->dims), *(image\->dims+1) ); \& ... \& } .Ve .PP Obviously a real wrapper would include more error and argument checking. .PP This might be compiled (e.g. Linux): .PP .Vb 1 \& cc \-shared \-o mycode.so mycode.c .Ve .PP In general Perl knows how to do this, so you should be able to get away with: .PP .Vb 1 \& perl \-MPDL::CallExt \-e callext_cc file.c .Ve .PP \&\fBcallext_cc()\fR is a function defined in PDL::CallExt to generate the correct compilation flags for shared objects. .PP If their are problems you will need to refer to you C compiler manual to find out how to generate shared libraries. .PP See t/callext.t in the distribution for a working example. .PP It is up to the caller to ensure datatypes of ndarrays are correct \- if not peculiar results or SEGVs will result. .SH "FUNCTIONS" .IX Header "FUNCTIONS" .SS "callext" .IX Subsection "callext" Call a function in an external library using Perl dynamic loading .PP .Vb 1 \& callext(\*(Aqfile.so\*(Aq, \*(Aqfoofunc\*(Aq, $x, $y); # pass ndarrays to foofunc() .Ve .PP The file must be compiled with dynamic loading options (see \f(CW\*(C`callext_cc\*(C'\fR). See the module docs \f(CW\*(C`PDL::Callext\*(C'\fR for a description of the \s-1API.\s0 .SS "callext_cc" .IX Subsection "callext_cc" Compile external C code for dynamic loading .PP Usage: .PP .Vb 1 \& % perl \-MPDL::CallExt \-e callext_cc file.c \-o file.so .Ve .PP This works portably because when Perl has built in knowledge of how to do dynamic loading on the system on which it was installed. See the module docs \f(CW\*(C`PDL::Callext\*(C'\fR for a description of the \s-1API.\s0 .SH "AUTHORS" .IX Header "AUTHORS" Copyright (C) Karl Glazebrook 1997. All rights reserved. There is no warranty. You are allowed to redistribute this software / documentation under certain conditions. For details, see the file \s-1COPYING\s0 in the \s-1PDL\s0 distribution. If this file is separated from the \s-1PDL\s0 distribution, the copyright notice should be included in the file.