如何从Perl XS模块调用不同C源文件中的函数?

时间:2014-04-23 12:28:49

标签: perl perl-module perl-xs

我正在使用Perl构建XS扩展。我有两个文件:

  1. C头文件(.h
  2. C源文件(.c
  3. 目前我所做的是将所有C文件代码放在XS文件的Model=之前,并在Model=之后包装我想要的函数。

    compliation没有问题,我可以从perl调用特定的函数。

    但我想将.xs文件与C文件分开。

    我希望.xs文件只包含wrap函数,这些函数将调用.c文件中的函数,但是当我这样做并运行dmake命令时得到错误代码129未定义引用' parse.c'文件。

    我尝试使用C和OBJECT属性包含.c文件用于WriteMakerFile并且仍然得到一个错误,任何想法如何将xs文件拆分为2个一个c文件和其他包含c函数的xs,它们是.c文件使用ExtUtils::MakeMaker

    示例将不胜感激。

2 个答案:

答案 0 :(得分:9)

这实际上非常简单:

hello.h

#ifndef H_HELLO
const char *hello(void);
#define H_HELLO
#endif

的hello.c

const char *
hello(void) {
    return "Hello";
}

Example.xs

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

#include "ppport.h"

#include "hello.h"

MODULE = My::Example        PACKAGE = My::Example       PREFIX = MY_

PROTOTYPES: DISABLE

const char *
MY_hello()
    CODE:
        RETVAL = hello();
    OUTPUT:
        RETVAL

吨/ MY-Example.t

use strict;
use warnings;

use Test::More;
BEGIN { use_ok('My::Example') };

is(My::Example::hello(), 'Hello', 'hello returns "Hello"');

done_testing;
[~/tmp/My-Example]$ prove -vb t/My-Example.t
t/My-Example.t ..
ok 1 - use My::Example;
ok 2 - hello returns "Hello"
1..2
ok
All tests successful.
Files=1, Tests=2,  0 wallclock secs 
( 0.04 usr  0.01 sys +  0.03 cusr  0.00 csys =  0.08 CPU)
Result: PASS

Makefile.PLh2xs生成。我改变的唯一方法是取消注释以下行:

# Un-comment this if you add C files to link with later:
 OBJECT => '$(O_FILES)', # link all the C files too

答案 1 :(得分:1)

我认为这是一篇比较老的文章,但我承认关键是正确的目录结构和文件放置。您必须将其他.c源文件放入xs文件所在的目录中。并将您的xs文件放入Makefile.PL所在的目录中。 (我假设您没有在Makefile.PL中将MULTIXS设置为1)。此放置限制的原因是,生成的Makefile中的CCCMD编译命令没有-o选项,因此所有输出目标文件都将放置在生成的Makefile所在的目录中。 在CPAN上,我发现/检查了一些模块,这些模块的源文件与xs文件位于不同的子目录中,但是它们覆盖了ExtUtils :: MakeMaker const_cccmd子目录,并在Makefile生成过程中即时添加-o选项。