小试 Perl 调用普通.so文件
首先通过cpan安装Inline和Inlne::C,让perl支持C
$sudo perl -MCPAN -e shell
cpan[2]>install Inline
cpan[2]>install Inline::C
然后做一个测试用的so库,如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 |
#include <stdio.h> #ifdef __cplusplus extern "C" { #endif int ctest(int z); #ifdef __cplusplus } #endif |
1 2 3 4 5 6 7 8 |
#include "libperl_c.h" int ctest(int z) { return z+8; } |
编译 $gcc -shared -o libperl_c.so libperl_c.c -I. 库很简单,只是为了测试,这个地方的#ifdef __cplusplus可以有也可以没有,但是如果用别人的库,或许就应该加上这段。区别是生成的库中导出函数的不同,如果形如ctest@MY_TEST_1.0,就需要添加,否则如果直接是ctest,就不用加,这一段应该和库的编译方式有关,后续再专门研究看看。编译后将库拷贝到/usr/lib下
测试perl调用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
#!/usr/bin/perl use Inline C => DATA => INC => '-I.' => LIBS => '-L. -lperl_c'; # MYEXTLIB => 'libperl_c.so'; my $x=1; print my_test(); print ""; __END__ __C__ #include <libperl_c.h> int my_test() { return ctest(9); } |
运行$./perl.pl
17
上面perl.pl中定义LIBS的另外一种方法(MYEXTLIB),测试不能工作,提示错误,原因未知:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
make: *** No rule to make target 'libperl_c.so', needed by 'subdirs'. Stop. A problem was encountered while attempting to compile and install your Inline C code. The command that failed was: "make > out.make 2>&1" with error code 2 The build directory was: /work/study/perl/_Inline/build/perl_pl_7e84 To debug the problem, cd to the build directory, and inspect the output files. Environment PATH = '/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/usr/games:/usr/local/games:/opt/jdk1.7.0_55/bin:/usr/local/mysql/bin:/work/RASP/tools/arm-bcm2708/arm-bcm2708hardfp-linux-gnueabi/bin' at ./perl.pl line 0. ...propagated at /usr/local/share/perl/5.20.2/Inline/C.pm line 869. INIT failed--call queue aborted. |
而且LIBS => '-L.'指定library路径的方式也不生效,必须将库放到系统目录。更夸张的是perl里面的#include必须用<>,如果写成#include "libperl_c.h"会出错。
参考的链接:
http://www.perlmonks.org/?node_id=151114
http://search.cpan.org/~rurban/Inline-0.54_02/C/C-Cookbook.pod
您好,请问我通过Inline::C 调用so文件的时候总是提示找不到C方法,大佬能否给个联系方式指导一下。感激不尽
好久不用这个了,都已经遗忘的差不多了,小小建议从so的提供者或者头文件着手,看一下导出函数的调用方法,从这里入手或许会有眉目