8

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

  1. AC 头文件 ( .h)
  2. AC 源文件 ( .c)

目前我所做的是将所有 C 文件代码Model=放在 XS 文件之前,并将我想要的函数包装在Model=.

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

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

我希望.xs文件只包含包装函数,这些函数将调用.c文件上的函数,但是当我这样做并运行dmake命令时,我得到错误代码 129 undefined reference to 'parse.c' file。

我尝试使用 WriteMakerFile 的 C 和 OBJECT 属性包含 .c 文件,但仍然收到错误消息,知道如何将 xs 文件拆分为 2 个一个 c 文件,另一个 xs 包装了作为 .c 文件一部分的 c 函数使用ExtUtils::MakeMaker

示例将不胜感激。

4

2 回答 2

10

这实际上相当简单:

你好.h

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

你好ç

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

例子.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

t/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]$ 证明 -vb t/My-Example.t
t/My-Example.t ..
好的 1 - 使用 My::Example;
好的 2 - 你好返回“你好”
1..2
好的
所有测试成功。
文件=1,测试=2,0 挂钟秒
(0.04 usr 0.01 sys + 0.03 cusr 0.00 csys = 0.08 CPU)
结果:通过

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

# 如果您添加 C 文件以供稍后链接,请取消注释:
 OBJECT => '$(O_FILES)', # 也链接所有 C 文件
于 2014-04-23T14:38:00.357 回答
1

我认为这是一篇相当老的帖子,但我承认关键是正确的目录结构和文件放置。您必须将其他 .c 源文件放入您的 xs 文件所在的同一目录中。并将您的 xs 文件放入您的 Makefile.PL 所在的目录中。(我假设您没有在 Makefile.PL 中将 MULTIXS 设置为 1)。这个放置限制的原因是生成的makefile中的CCCMD编译命令没有-o选项,所以所有的输出目标文件都会放在你生成的Makefile所在的目录中。在 CPAN 上,我发现/检查了一些具有与 xs 文件不同的子目录中的源文件的模块,但它们在 Makefile 生成期间会覆盖 ExtUtils::MakeMaker const_cccmd sub 和附加 -o 选项。

于 2019-10-28T15:00:37.973 回答