Embed perl in c/c++, C调用perl, perl调用C 技术详解

本文详细介绍了如何从Perl环境中调用C语言编写的函数,包括必要的映射关系建立及回调函数的应用。通过实例展示了DEP.pm模块与C代码之间的交互方式,并提及了Perl在C中的调用注意事项。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

我先介绍要从perl里面调用C的函数的处理方法 :

请大家下看下面的代码, 其中关键的地方为 void boot_DEP (pTHX_ CV* cv) 函数, 还有 newXS("DEP::bootstrap", boot_DEP, file);

这两个函数代表的意思是: DEP为 perl 调用C的模块名, 也就是说我们还需要写一个 DEP.pm的模块,让其他的perl模块编译的时候不至于编译出错。

newXS 这个函数比较特殊,相当于perl会做一个 key--->Value的映射关系, DEP.pm 里面的bootstrap函数调用会映射为C里面的

boot_DEP函数调用。

函数 xs_init 这个函数是perl内置的回调函数, perl会调用它, 在xs_init函数里面会调用boot_DEP函数, boot_DEP函数里面的

newXS ("DEP::shutdown", xs_shutdown, "COMMON.c"); 相当于什么呢 ?

相当于做了key---->value 的映射关系 , 当perl调用 DEP模块的shutdown时, 就会变为调用C的 xs_shutdown函数。

#include <EXTERN.h> #include <perl.h> #include <XSUB.h> EXTERN_C void boot_DynaLoader (pTHX_ CV* cv); EXTERN_C void boot_DEP (pTHX_ CV* cv); EXTERN_C void xs_init(pTHX) { char *file = __FILE__; dXSUB_SYS; newXS("DEP::bootstrap", boot_DEP, file); /* DynaLoader is a special case */ newXS("DynaLoader::boot_DynaLoader", boot_DynaLoader, file); } XS(xs_shutdown) { dXSARGS; /* local declarations for XS */ /* TODO: add some protection to this function */ int a = 0; XSRETURN(0); } void boot_DEP (pTHXo_ CV* cv) { //newXS ("DEP::XXPRINTS", xs_XXPRINTS, "COMMON.c"); newXS ("DEP::shutdown", xs_shutdown, "COMMON.c"); }

下面在看看DEP.pm这个模块的代码

#! /usr/bin/perl -w package DEP; use strict; our @ISA = qw(Exporter); use Exporter; our @EXPORT_OK = qw(shutdown); bootstrap DEP; # tie standard input, standard output, standard error to our I/O module tie (*STDIN, 'DEP::IO'); tie (*STDOUT, 'DEP::IO'); tie (*STDERR, 'DEP::Debug'); sub shutdown(); # XSUB package DEP::IO; sub TIEHANDLE { bless [], shift } sub READLINE; # XSUB sub READ; # XSUB sub GETC; # XSUB sub PRINT; # XSUB package DEP::Debug; sub TIEHANDLE { bless [], shift } sub PRINT; # XSUB

下来随便写个 xxx.pl文件, 内容如下, 在C中的xs_shutdown函数中设置个断点, 调试启动,就会看到perl调用到C里面了。

经过本人测试, 有个比较奇怪的地方,就是在 xxx.pl文件的开始的地方 用use DEP; 把sub bar 函数中的 require DEP; 去掉,

会造成 perl无法调用到C的问题, 不知道为什么, 只能像下面这样使用才能调用到C的代码里面。

use strict; sub bar { print "***** sub bar/n"; require DEP; DEP::shutdown (); print "bar finish/n"; }

C调用Perl就比较简单了, 需要注意的是 PERL_SYS_INIT3(argc,argv,env); 很关键。 最好在main函数入口就调用该函数。

还有就是 在 perl_construct 函数之前需要设置 PL_perl_destruct_level 为1, 具体代码如下:

PL_perl_destruct_level = 1;

perl_construct ( poPerlInterpreter );
PL_exit_flags |= PERL_EXIT_DESTRUCT_END;

另外是如果同一个进程内需要多个perl的解释器同时运行的话, 在调用perl解释器处理事务的时候需要对当前的perl解释器进行设置,

用 PERL_SET_CONTEXT 进行设置当前的解释器。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值