perl C/C++ 扩展(四)
在前面三篇博客中,我们了解到如何使用c/c++ 扩展自己的perl 库,但是博主在学习过程中,对动态库或静态库的加载不是十分了解,后来自己又细挖一下。后来就有了这篇博文,再后来,没有再后来了,囧!!
我们先来看看 perl c/c++ 扩展(二)中的 Makefile.PL
WriteMakefile(
NAME => 'two_test',
VERSION_FROM => 'lib/two_test.pm', # finds $VERSION
PREREQ_PM => {}, # e.g., Module::Name => 1.1
($] >= 5.005 ? ## Add these new keywords supported since 5.005
(ABSTRACT_FROM => 'lib/two_test.pm', # retrieve abstract from module
AUTHOR => 'root <root@>') : ()),
LIBS => [''], # e.g., '-lm'
DEFINE => '', # e.g., '-DHAVE_SOMETHING'
INC => '-I.', # e.g., '-I. -I/usr/include/other'
# Un-comment this if you add C files to link with later:
# OBJECT => '$(O_FILES)', # link all the C files too
MYEXTLIB => 'mylib/libchen.a'
);
注意:
我们第一次写时,是没有填写 LIBS 与 INC 字段的,但是我们增加了一个 MYEXTLIB 的字段,指定我们要增加‘mylib/libchen.a'的静态库
由于在perl c/c++ 扩展(三)中,我们是使用了***.so 动态库来编译,而且也能正常工作,所以我就想,在(二)里,肯定也能调用动态库。
于是对原程序改动了一下,编译出一个libchen.so的文件,放在mylib/ 目录下。
修改一下Makefile.PL 脚本
MYEXTLIB => 'mylib/libchen.so'
还是使用之前的命令
perl Makefile.Pl
make
make install
编译通过,但在运行测试脚本时出错,说是找不到动态库。
这个问题简单,给环境变量LD_LIBRARY_PATH 添加一下libchen.so路径即可。再次运行测试脚本,通过。
由于需要添加环境变量这个细节又引起我的注意,在使用中,我知道perl c/c++ 扩展(三) 的编译方法不依赖环境变量的,也就是说,无论切换到什么窗口都可成功运行测试脚本。
我们来看看(三)是怎么写Makefile.PL的
WriteMakefile(
NAME => 'three_test',
VERSION_FROM => 'lib/three_test.pm', # finds $VERSION
PREREQ_PM => {}, # e.g., Module::Name => 1.1
($] >= 5.005 ? ## Add these new keywords supported since 5.005
(ABSTRACT_FROM => 'lib/three_test.pm', # retrieve abstract from module
AUTHOR => 'root <root@>') : ()),
LIBS => ['-L./ -lduck'], # e.g., '-lm'
DEFINE => '', # e.g., '-DHAVE_SOMETHING'
'CC' => $CC,
'LD' => '$(CC)',
INC => '-I.', # e.g., '-I. -I/usr/include/other'
# Un-comment this if you add C files to link with later:
# OBJECT => '$(O_FILES)', # link all the C files too 'XSOPT' => '-C++',
'TYPEMAPS' => ['perlobject.map']
);
我们看到,除了新增了XSOPT TYPEMAPS CC LD字段外,还修改了 LIBS INC字段。
而且LIBS 字段的内容就是g++ 的lib 库,INC 字段就是头文件的地址。
所以我们将(二) 的Makefile.PL修改一下,变成
WriteMakefile(
NAME => 'two_test',
VERSION_FROM => 'lib/two_test.pm', # finds $VERSION
PREREQ_PM => {}, # e.g., Module::Name => 1.1
($] >= 5.005 ? ## Add these new keywords supported since 5.005
(ABSTRACT_FROM => 'lib/two_test.pm', # retrieve abstract from module
AUTHOR => 'root <root@>') : ()),
LIBS => ['-Lmylib -lchen'], # e.g., '-lm'
DEFINE => '', # e.g., '-DHAVE_SOMETHING'
INC => '-Imylib', # e.g., '-I. -I/usr/include/other'
# Un-comment this if you add C files to link with later:
# OBJECT => '$(O_FILES)', # link all the C files too
#MYEXTLIB => 'mylib/libchen.so'
);
修改了 LIBS INC 字段,指定动态库的地址为-Lmylib,使用chen的库-lchen
INC字段写chen.h 头文件的地址。
注意,这时候,我们还是沿用libchen.so的动态库。
编译并按装
perl Makefile.PL
make
make install
运行测试脚本,OK
切换一个窗口(等于没有执行export LD_LIBRARY_PATH=${LD_LIBRARY_PATH}:/learn/perl/two_test/mylib) ,再运行测试脚本,依然OK。
但是当我们将mylib目录下的动态库改名,变成libchen.so.bak。再运行测试脚本,失败,报错说找不到libchen.so的库
错误信息:/usr/local/lib/perl/5.14./auto/two_test/two_test.so' for module two_test: libchen.so: 无法打开共享对象文件: 没有那个文件或目录 at /usr/share/perl/5.14/XSLoader.pm line 71
到这里,我们就可以知道了,实质上在LIBS 字段写上库名,应该是在生成Makefile时,将绝对路径包含了,并且自动添加到环境变量了,所以使用动态库生成的perl 扩展,运行环境都需要将动态库加入环境变量里。
上面的测试,扩展包还需要运行环境有动态库,对于移植性来说,多有不便。所以我们还是希望使用静态库编译。
方法很简单,只要将libchen.so 动态库替换成 libchen.a 静态库,在重新编译扩展包就好了。
perl Makefile.PL
make
make install
这次,无论你怎造,perl 的测试程序都能正确运行。
我们再回头看看(二)的Makefile.PL
WriteMakefile(
NAME => 'two_test',
VERSION_FROM => 'lib/two_test.pm', # finds $VERSION
PREREQ_PM => {}, # e.g., Module::Name => 1.1 ($] >= 5.005 ? ## Add these new keywords supported since 5.005
(ABSTRACT_FROM => 'lib/two_test.pm', # retrieve abstract from module
AUTHOR => 'root <root@>') : ()),
LIBS => [''], # e.g., '-lm'
DEFINE => '', # e.g., '-DHAVE_SOMETHING'
INC => '-I.', # e.g., '-I. -I/usr/include/other'
# Un-comment this if you add C files to link with later:
# OBJECT => '$(O_FILES)', # link all the C files too
MYEXTLIB => 'mylib/libchen.a'
);
它也是使用了libchen.a静态库,经过测试,运行时也能不再依赖库了。
总结:
无论是使用MYEXTLIB 字段,还是通过指定LIBS INC来指向库文件,只要是使用静态库编译,扩展包都能脱离库的依赖。
perl C/C++ 扩展(四)的更多相关文章
- perl C/C++ 扩展(五)
perl 的C++扩展,返回值为自定义类型. 在 perl C/C++扩展(三) 中,我已经介绍了,如何让perl 认识 c++的类,但是前面的介绍中,包括我参考的博客http://chunyemen ...
- perl C/C++ 扩展(二)
第二讲perl 加载c/c++的库 先通过h2xs 创建一个新的工程 h2xs -A -n two_test 进入目录 cd two_test 创建一个mylib文件夹,存放静态库 mkdir myl ...
- perl C/C++ 扩展(三)
第三讲扩展库使用c++实现,在调用函数后,返回对象变量,perl 能正确使用所有对象成员 使用h2xs 命令生成初始文件 h2xs -A -n three_test 登录目录 cd three_tes ...
- perl C/C++ 扩展(一)
通过h2xs 中间件,我们可以快速的使用c或则C++ 库来实现perl 扩展功能 第一讲:跑通hello world 程序******************************我们使用命令:h2 ...
- Unity扩展 四种Menu的区别
[MenuItem("Tools\AddColor")] : 在Unity菜单中添加一种快捷,执行public static方式 [AddComponentMenu(" ...
- (转载)CSV 文件处理 PERL
http://cn.perlmaven.com/how-to-read-a-csv-file-using-perl http://search.cpan.org/~hmbrand/Text-CSV_X ...
- perl语言书籍教程推荐
互动出版网计算机频道.为您推荐关于perl语言的书籍教程.包括perl push.perl chomp以及perl python等perl语言内容. perl语言书籍一.<Perl语言编程 第四 ...
- centos yum 安装 mongodb 以及php扩展
centos yum 安装 mongodb 以及php扩展 投稿:hebedich 字体:[增加 减小] 类型:转载 MongoDB是一个基于分布式文件存储的数据库.由C++语言编写.旨在为WEB应用 ...
- Perl中的正则表达式
转自:http://c20031776.blog.163.com/blog/static/684716252013624383887/ Perl 程序中,正则表达式有三种存在形式 分别是 (1 模式匹 ...
随机推荐
- Sping框架概述
一.什么是spring框架 spring是J2EE应用程序框架,是轻量级的IoC和AOP的容器框架,主要是针对javaBean的生命周期进行管理的轻量级容器,可以单独使用,也可以和Struts框架,i ...
- extjs中新建窗体时,给窗体添加背景图片不显示问题之一
1.在extjs中新建窗体时,给窗体添加背景图片不显示,例如下面的代码. 不显示的原因:因为设置了 layout: 'fit', Ext.create('Ext.Window', { title: ...
- 九度OJ 1118:数制转换 (进制转换)
时间限制:1 秒 内存限制:32 兆 特殊判题:否 提交:3873 解决:1494 题目描述: 求任意两个不同进制非负整数的转换(2进制-16进制),所给整数在long所能表达的范围之内. 不 ...
- xml 基础属性
xml属性 对应的方法 说明 android:alpha setAlpha(float) 设置组件的透明度(0——1) android:background setBackgroundResource ...
- 基本动画、复合动画设置 平移、缩放、旋转、透明度 编码实现 xml实现
public class VAActivity extends Activity { private ImageView iv_animation; private TextView tv_anima ...
- Struts多个文件上传
Struts2多个文件上传 10级学员 韩晓爽课堂笔记 多个文件上传分为List集合和数组,下面我们着重介绍一下list集合的上传.都大同小异. 一 介绍 1. 在struts2文件上传的时候要先导入 ...
- jni native macOS
参考自:http://mrjoelkemp.com/2012/01/getting-started-with-jni-and-c-on-osx-lion/ 1 ,创建HelloWorld,如: 说明: ...
- 简述arp协议的工作原理
在每台安装有TCP/IP协议的电脑里都有一个ARP缓存表,表里的IP地址与MAC地址是一一对应的,如: 我们以主机A(192.168.1.5)向主机B(192.168.1.1)发送数据为例.当发送数据 ...
- centos6.5安装jdk
1.查看Linux环境自带JDK 使用命令:# rpm -qa|grep gcj 显示内容其中包含相应信息# java-x.x.x-gcj-compat-x.x.x.x-xxjpp# java-x.x ...
- codeforces 465C.No to Palindromes! 解题报告
题目链接:http://codeforces.com/problemset/problem/464/A 题目意思:给出一个长度为 n 且是 tolerable 的字符串s,需要求出字典序最小的长度也为 ...