小试 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
#ifdef __cplusplus
extern"C"{
#endif
intctest(intz);
#ifdef __cplusplus
}
#endif
1
2
3
4
5
6
7
8
#include "libperl_c.h"
intctest(intz)
{
returnz+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
useInlineC=>DATA=>
INC=>'-I.'=>
LIBS=>'-L. -lperl_c';
# MYEXTLIB => 'libperl_c.so';
my$x=1;
printmy_test();
print"";
__END__
__C__
#include
intmy_test()
{
returnctest(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:***Noruletomaketarget'libperl_c.so',neededby'subdirs'.Stop.
AproblemwasencounteredwhileattemptingtocompileandinstallyourInline
Ccode.Thecommandthatfailedwas:
"make > out.make 2>&1"witherrorcode2
Thebuilddirectorywas:
/work/study/perl/_Inline/build/perl_pl_7e84
Todebugtheproblem,cdtothebuilddirectory,andinspecttheoutputfiles.
EnvironmentPATH='/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.plline0.
...propagatedat/usr/local/share/perl/5.20.2/Inline/C.pmline869.
INITfailed--callqueueaborted.
而且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
相关