c - 使用 perl XS 链接到 C 共享库

标签 c linux perl makefile perl-xs

我是 PERL XS 的新手,有一个关于调用用 Ansi C 编写的共享库 (.so) 的问题。我似乎找不到任何好的示例来准确说明如何执行此操作。我浏览了位于此处的入门教程(Hello World 等):

http://www.lemoda.net/xs/perlxstut/

我想修改它以调用 C 共享库中名为 cpro_supported 的函数。

libpmap.so:

extern  int cpro_supported(int);

这里有一些基础知识:

生成文件.PL:

use 5.008005;
use ExtUtils::MakeMaker;
# See lib/ExtUtils/MakeMaker.pm for details of how to influence
# the contents of the Makefile that is written.
WriteMakefile(
    NAME              => 'test',
    VERSION_FROM      => 'lib/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/test.pm', # retrieve abstract from module
       AUTHOR         => 'A. U. Thor <johnm@localdomain>') : ()),
    LIBS              => ['-lm'], # 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
);

用“-L 路径到 .so 文件”修改了 LIBS 参数,但这似乎没有帮助。

测试.xs:

#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"

#include "ppport.h"


MODULE = test       PACKAGE = test      

int
cpro_it(monitor)
    int monitor
CODE:
    RETVAL = cpro_supported(monitor);
OUTPUT:
    RETVAL

void hello()
CODE:
printf("Hello, World!\n");

int
is_even(input)
    int input
CODE:
    RETVAL = (input % 2 == 0);
OUTPUT:
    RETVAL

void
round(arg)
    double  arg
CODE:
    if (arg > 0.0) {
        arg = floor(arg + 0.5);
    } else if (arg < 0.0) {
        arg = ceil(arg - 0.5);
    } else {
        arg = 0.0;
    }
OUTPUT:
    arg

测试.t:

# Before `make install' is performed this script should be runnable with
# `make test'. After `make install' it should work as `perl test.t'

#########################

# change 'tests => 1' to 'tests => last_test_to_print';

use Test::More tests => 10;
use test;
BEGIN { use_ok('test') };

#########################

# Insert your test code below, the Test::More module is use()ed here so read
# its man page ( perldoc Test::More ) for help writing this test script.

is (test::is_even(0), 1);
is (test::is_even(1), 0);
is (test::is_even(2), 1);
my $i;
$i = -1.5; test::round($i); is( $i, -2.0 );
$i = -1.1; test::round($i); is( $i, -1.0 );
$i = 0.0; test::round($i);  is( $i,  0.0 );
$i = 0.5; test::round($i);  is( $i,  1.0 );
$i = 1.2; test::round($i);  is( $i,  1.0 );
my $mon;
$mon = test::cpro_it(23); is($mon,1);

当我运行 make test 时,我收到以下错误:

PERL_DL_NONLAZY=1/usr/bin/perl "-MExtUtils::Command::MM""-e""test_harness(0, 'blib/lib', 'blib/arch')"t/*.t t/测试....

无法为模块测试加载“/home/johnm/tmp/test/blib/arch/auto/test/test.so”:/home/johnm/tmp/test/blib/arch/auto/test/test.so: undefined symbol: cpro_supported 在/usr/lib/perl5/5.8.5/i386-linux-thread-multi/DynaLoader.pm 第 230 行。 在 t/test.t 第 9 行

在 t/test.t 第 9 行的 require 中编译失败。

BEGIN 失败——编译在 t/test.t 第 9 行中止。 看起来你的测试在它可以输出任何东西之前就死了。 t/测试....可疑 测试返回状态 255 (wstat 65280, 0xff00) 死了。失败的测试 1-10 10/10 次测试失败,0.00% 正常

Failed Test Stat Wstat Total Fail Failed 失败列表

t/test.t 255 65280 10 20 200.00% 1-10 失败的 1/1 测试脚本,0.00% 没问题。 10/10 子测试失败,0.00% 正常。

make: * [test_dynamic] 错误 2

关于这里缺少什么的任何想法?

谢谢!!

最佳答案

您还没有告诉它链接到包含 cpro_supported 的库。 (-L 选项只是告诉链接器它可以在哪里找到库;它实际上并没有告诉它与任何其他库链接。您需要一个 - l 选项。)

MYEXTLIB 适用于作为模块构建过程的一部分构建的 C 库,而不是安装在系统上的库。试试这个:

LIBS => ['-L/home/johnm/lib -lpmap -lmap -llang -ldispatch -led -lm -lncurses'],

关于c - 使用 perl XS 链接到 C 共享库,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19569719/

相关文章:

perl - 如何在 Perl 中解析 .pdf 文件?

无法获取字符串数组来复制一个随机值

c - 链表打印功能不起作用

c - 本地 Linux UDP sendto "Bad address"错误

c++ - 内存布局问题

python - 在 Ubuntu 10.04 中安装 Dropbox python SDK

Perl WWW::Mechanize::Firefox 和输入类型文件

perl - 使用 perl 的 qx{}/ `...` 运算符和参数列表

C从文件中读取utf字符

linux - 在 Linux 中查找特定模式