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 <[email protected]>‘) : ()),
    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 <[email protected]>‘) : ()),
    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 <[email protected]>‘) : ()),
    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.2/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 <[email protected]>‘) : ()),
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++ 扩展(四),布布扣,bubuko.com

时间: 2024-10-05 03:03:42

perl C/C++ 扩展(四)的相关文章

perl C/C++ 扩展(五)

perl 的C++扩展,返回值为自定义类型. 在 perl C/C++扩展(三) 中,我已经介绍了,如何让perl 认识 c++的类,但是前面的介绍中,包括我参考的博客http://chunyemen.org/archives/493,都提到,返回值必须是基础类型.对于开发者而言,如果返回值只能是基础类型,那么对于扩展的开发热情就大大降低了.楼主排除万难,终于在<高级perl编程(第二版)>.((美)simon cozens)一书的第十八章与第二十章中得到些许启发. 下面我来介绍一下玩法. 首

perl C/C++ 扩展(二)

第二讲perl 加载c/c++的库 先通过h2xs 创建一个新的工程 h2xs -A -n two_test 进入目录 cd two_test 创建一个mylib文件夹,存放静态库 mkdir mylib c程序头文件chen.h #include<stdio.h> void chen(char *); c程序代码chen.c #include "chen.h" void chen(char * name){ printf("input string is : %

perl C/C++ 扩展(一)

通过h2xs 中间件,我们可以快速的使用c或则C++ 库来实现perl 扩展功能 第一讲:跑通hello world 程序******************************我们使用命令:h2xs -A -n test它会帮助你建立一个test的文件夹,里面已经初始化部分文件了 进入test目录 cd test 打开文件test.xs vi test.xs 原文件内容为: #include "EXTERN.h" #include "perl.h" #incl

perl C/C++ 扩展(三)

第三讲扩展库使用c++实现,在调用函数后,返回对象变量,perl 能正确使用所有对象成员 使用h2xs 命令生成初始文件 h2xs -A -n three_test 登录目录 cd three_test c++ 头文件 #ifndef INCLUDED_DUCK_H #define INCLUDED_DUCK_H 1 #include <string> using std::string; class Duck { public: Duck(char*); char* getName(); v

Perl学习笔记(四)--子程序

定义子程序: 要定义自己的子程序,可使用关键字sub,子程序名(不包含与号)以及用花括号封闭起的代码块,例如: 1 sub marine{ 2 $n +=1; #全局变量 $n 3 Print “Hello,sailor number $n \n”; 4 } 子程序不需要事先声明 子程序的定义是全局的,不存在私有子程序 假如定义两个重名的子程序,后面的子程序会覆盖掉前面的那个 调用子程序 1 &marine; 返回值 子程序中最后一次运算的结果都会被自动当成子程序的返回值 参数 要传递参数列表到

测试扩展(四)——Tomcat和http请求

一.前言 这边博客主要做一个总结,记录Tomcat和http请求,通过阅读大佬们的博客,得出以下结论: servlet是java为了支持动态的交互网页所定制的标准 Tomcat为servlet的运行环境,可以称之为容器 server是Tomcat的运行环境(sever.xml) Tomcat支持两种协议:HTTP和AJP(apache 私有协议,用于tomcat和apache静态服务器通信) 基于以上几点,本篇博客将介绍:Tomcat源码结构.servlet结构.Tomcat核心类图.Tomca

Unity扩展 四种Menu的区别

[MenuItem("Tools\AddColor")] :  在Unity菜单中添加一种快捷,执行public static方式 [AddComponentMenu("Tools/AddComponent")]:    在Unity菜单中添加一种快捷,快速为某一个游戏物体添加一个组件 [ContextMenu("添加文本")]: 点击组件右键,添加一种快速执行组件的某方法方式 [ContextMenuItem("添加属性",

perl语言书籍教程推荐

互动出版网计算机频道.为您推荐关于perl语言的书籍教程.包括perl push.perl chomp以及perl python等perl语言内容. perl语言书籍一.<Perl语言编程 第四版(上下册)(影印版)> <perl语言编程>在1991年第一次出版时就无可争议地成为了perl的圣经,它现在依然是这门高实用性语言的入门指南. perl语言书籍二.<Perl语言入门(第六版.中文版)(Perl程序员必读之作)(china-pub首发)> 最具权威性的o'rei

(转载)CSV 文件处理 PERL

http://cn.perlmaven.com/how-to-read-a-csv-file-using-perl http://search.cpan.org/~hmbrand/Text-CSV_XS-1.09/CSV_XS.pm 读取并处理文本是 Perl 的强项.有时候你有一个CSV (Comma-separated values)文件,需要从中提取信息,该怎么办呢? 本节给出三个解决方案. 如果你的CSV文件比较简单,简单的Perl脚本就能轻松搞定.这里是我们的方案一. 第二个方案能够对