使用XS在perl上公开c函数

时间:2014-07-18 20:07:52

标签: perl xs

我有这种格式的多个c函数:

int function(const char* input, size_t len, char result[]) ;

其中int是返回类型;

result[]包含函数填充的字符串

最好将这样的函数编写为XS并将其暴露在perl上:

  1. 获取函数的返回值

  2. 获取perl上的char result []值

  3. 我尝试了以下但下面只返回了返回值

    int
    my_function(a,b,c)
        const char *  a
        long            b
        const char *    c
        CODE:
        RETVAL =function(a,b,c)
        OUTPUT:
        RETVAL
    

    任何帮助将不胜感激?

3 个答案:

答案 0 :(得分:4)

创建一个新目录,并将以下文件复制到其中:

<强> ./ Example.xs

#include "EXTERN.h"
#include "perl.h"
#include "XSUB.h"
#include "ppport.h"    
#include "const-c.inc"

int my_function(const char* input, size_t len, char result[])
{
    strcpy(result, "the answer");
    return 42;
}

MODULE = Acme::XS::Example        PACKAGE = Acme::XS::Example

INCLUDE: const-xs.inc
PROTOTYPES: DISABLE

void
my_xsub (input, len)
    char *input
    int len
PPCODE:
{
    char result[10];
    int got = my_function(input, len, result);

    /* create a new scalar from an int, and push onto stack */
    PUSHs( newSViv(got) );
    /* create a new scalar from a string, and push onto stack */
    PUSHs( newSVpv(result, 0) );

    XSRETURN(2);  /* two items returned */
}

<强> ./ LIB / Acme公司/ XS / Example.pm

use 5.010001;
use strict;
use warnings;
use XSLoader ();

package Acme::XS::Example;
our $VERSION   = '0.001';
__PACKAGE__->XSLoader::load($VERSION);
1;

<强> ./吨/ basic.t

use strict;
use warnings;
use Test::More;

use_ok('Acme::XS::Example');

my @results = Acme::XS::Example::my_xsub("Hello world", 666);

is_deeply(
    \@results,
    [ 42, "the answer" ],
    "got expected results",
) or diag explain(\@results);

done_testing;

<强> ./ Makefile.PL

use strict;
use Devel::PPPort;
use ExtUtils::MakeMaker 6.6303;
use ExtUtils::Constant;

Devel::PPPort::WriteFile();

ExtUtils::Constant::WriteConstants(
    NAME         => 'Acme::XS::Example',
    NAMES        => [],
    DEFAULT_TYPE => 'IV',
    C_FILE       => 'const-c.inc',
    XS_FILE      => 'const-xs.inc',
);

WriteMakefile(
    NAME       => 'Acme::XS::Example',
    DISTNAME   => 'Acme-XS-Example',
    VERSION    => '0.001',
    ABSTRACT   => 'an example XS thingy',
    AUTHOR     => ['Toby Inkster <tobyink@cpan.org>'],
    LICENSE    => 'perl_5',
    MIN_PERL_VERSION  => '5.010001',
    PREREQ_PM  => {
        'XSLoader'             => 0,
    },
    TEST_REQUIRES => {
        'Test::More'           => '0.96',
    },
    CONFIGURE_REQUIRES => {
        'Devel::PPPort'        => 0,
        'ExtUtils::Constant'   => 0,
        'ExtUtils::MakeMaker'  => '6.6303',
    },
    LIBS       => [''],
    DEFINE     => '',
    INC        => '-I.',
    test       => { TESTS => "t/*.t" },
    clean      => { FILES => 'const-c.inc const-xs.inc ppport.h' },
);

你的骨架可以随身携带。 : - )

构建并测试它:

perl Makefile.PL
make
make test

答案 1 :(得分:1)

程序h2xs可用于创建perl / XS模块,该模块充当C代码的包装器。我认为您要创建一个包含函数原型的头文件。

阅读h2xs的手册页以获取详细信息。另外,看看here

答案 2 :(得分:0)

perl函数(也是XS函数)可以返回多个值 您将需要使用PPCODE而不是CODE,并将多个变量作为结果推送到堆栈中。例如,请参阅PPCODE的perlxs文档。