2010-10-29 4 views
12

Хорошо, это очень интересный вопрос, и, возможно, не может быть простого способа сделать это, но решил, что я выброшу его там, прежде чем решить, что изменение Perl - это мой основной ответ.Вызов функции C из Perl внутри встроенного приложения C

Итак, у меня есть приложение C, которое вызывает Perl-скрипты встроенным способом. Все это прекрасно работает и денди, и это довольно удивительно, что я могу передавать информацию и получать информацию. ОДНАКО, теперь на следующее завоевание; Мне нужно разрешить моим встроенным скриптам (сценариям) иметь возможность вызывать некоторые функции в приложении C, которые ORIGINALLY CALLED IT.

Это важно, потому что XSUB потребует от него внешней библиотеки; но я не хочу, чтобы это была внешняя библиотека, я хочу, чтобы это был прямой вызов функции (ов) C. Теперь, возможно, это можно сделать через XSUB, и я только что читал и понимал это неправильно.

Application -(run)-> Perl 

Application <-(function_x())- Perl 

Application -(returnfunction_x)-> Perl 

Причина этого не может быть внешняя библиотека, потому что я, опираясь на данные, которые только созданных/сохраненных в приложении.

+0

Способ сделать это в Python - создать функцию FFI в C, а затем добавить ее в словарь виртуального модуля, который импортирует скрипт Python. Не уверен, что все сделано так же в Perl. –

ответ

7

XSUB фактически не требуют наличия внешней библиотеки. Они просто предоставляют возможность вызова функции c из perl-пространства и обеспечивают некоторое удобство при сопоставлении вызывающих соглашений между C и Perl.

Все, что вам нужно сделать, это зарегистрировать XSUB, которые вы скомпилировали в приложение для встраивания с помощью встроенного интерпретатора perl.

#include "XSUB.h" 

XS(XS_some_func); 
XS(XS_some_func) 
{ 
    dXSARGS; 
    char *str_from_perl, *str_from_c; 

    /* get SV*s from the stack usign ST(x) and friends, do stuff to them */ 
    str_from_perl = SvPV_nolen(ST(0)); 

    /* do your c thing calling back to your application, or whatever */ 
    str_from_c = some_c_func(str_from_perl); 

    /* pack up the c retval into an sv again and return it on the stack */ 
    mXPUSHp(c_str); 
    XSRETURN(1); 
} 

/* register the above XSUB with the perl interpreter after creating it */ 
newXS("Some::Perl::function", XS_some_func, __FILE__); 

При вложении Perl, такого рода вещи, как правило, делается в функции xs_init вы передаете parse_perl.

EXTERN_C void boot_DynaLoader (pTHX_ CV* cv); 

static void 
xs_init (pTHX) 
{ 
    newXS("Some::Perl::function", XS_some_func, __FILE__); 
    /* possibly also boot DynaLoader and friends. perlembed has more 
    * details on this, and ExtUtils::Embed helps as well. */ 
    newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file); 
} 

perl_parse(my_perl, xs_init, argc, my_argv, NULL); 

После того, что вы будете иметь возможность звонить в XSub в Some::Perl::function из PERL пространства, и что XSUB в свою очередь, является свободным перезвонить к приложению в любом случае он хочет.

+0

Итак, первый раздел, который вы вставили, входит в файл .xs? – Suroot

+0

Это код C, поэтому я хотел бы поместить его в файл '.c', но я сомневаюсь, что любой правильный компилятор C заботится о расширении файлов, которые вы просите его скомпилировать :-) – rafl

+1

Теперь все имеет смысл; Я думал, что материал newXS на самом деле просто говорит о загрузке модулей. Не удалось найти много документации о perl-xs; Самый оцененный сэр! – Suroot

Смежные вопросы