Разоблачение функции c на Perl с использованием XS
У меня есть несколько функций c в этом формате:
int function(const char* input, size_t len, char result[]) ;
где int
тип возвращаемого значения;
result[]
содержит строку, которую заполняет функция
что лучше всего написать такую функцию как XS и выставить ее на Perl:
получить возвращаемое значение функции
получить значение char [] для perl
Я попробовал ниже, но ниже только вернуть возвращаемое значение
int
my_function(a,b,c)
const char * a
long b
const char * c
CODE:
RETVAL =function(a,b,c)
OUTPUT:
RETVAL
Любая помощь будет оценена?
3 ответа
Создайте новый каталог и скопируйте в него следующие файлы:
./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;
./t/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
Программа h2xs
может быть использован для создания модуля perl/XS, который действует как обертка вокруг вашего C-кода. Я думаю, что вы захотите создать заголовочный файл с прототипами ваших функций.
Прочитайте справочные страницы для h2xs
для деталей. Кроме того, посмотрите здесь
Функция perl (также функция XS) может возвращать более одного значения.
Вам нужно будет использовать PPCODE вместо CODE и поместить несколько переменных в стек в качестве результата. см. документацию perlxs для PPCODE, например.