我想将Perl嵌入到c ++应用程序中,并且正在寻找一种通过newXS((从perl调用c ++的方法。除了函数指针之外,我还需要将自定义指针关联到 newXS(( 创建的 CV。指针包含C++上下文。我不想为此使用全局变量。有没有常用的方法可以做到这一点?
在更广泛的范围内,问题可能是天气有可能向 newXS(( 创建的 CV 添加闭包,以及在调用向其注册的 c 函数时如何引用它。CvPADLIST(( 似乎是完美的地方,但是对于 XSubs 来说,在设置PERL_IMPLICIT_CONTEXT时似乎无效(在 perl 的 pad.c 开头注释(。可以忽略吗?还有其他地方可以放置简历本地数据吗?
一种可能性是将PERL_MAGIC_ext魔法附加到 SV 上,如 perlguts 中所述:
int m_free (pTHX_ SV *sv, MAGIC* mg){ ... }
STATIC MGVTBL my_vtbl = { 0, 0, 0, 0, m_free, 0, 0, 0 };
struct ctx;
XS(XS_some_func)
{
...
MAGIC *mg;
if ((mg = mg_findext((SV*)cv, PERL_MAGIC_ext, &my_vtbl))) {
ctx *priv = (ctx *)mg->mg_ptr;
}
...
}
并在通过 newXS(( 创建 CV 时分配魔法:
ctx c;
...
CV *cv = newXS(index, XS_some_func, __FILE__);
MAGIC *mg = sv_magicext((SV *)cv,
0,
PERL_MAGIC_ext,
&my_vtbl,
(const char*)&c,
sizeof(c));
CV
中有一个ANY
槽,可用于自定义数据并使用CvXSUBANY(cv)
访问。例如:
CvXSUBANY(cv).any_ptr = my_ptr;
此插槽通常用于存储 XS 别名的索引和 XS 接口的函数指针。
最简单(也可能是最好的(方法可能是使上下文明确 - 公开面向对象的 API 并使用方法而不是函数。在 Perl 代码中创建类的new
实例时,您将上下文放入该对象中。当您的 XSUB 作为该对象上的方法调用时,它将接收上下文作为第一个参数(即ST(0)
(。
从 XS/C++ 的角度来看,这基本上等同于 melpomene 的评论,但不需要额外的包装器闭包。
如果每个进程只有一个上下文,那么使用全局变量也是合法的——也许是一种必要的邪恶。还比较 在 XS中安全地存储静态数据。
我知道没有将额外数据直接与 xsubs 相关联的机制。也许可以用CV来拉一些魔力,但这听起来不必要地复杂,除非你不能把你的上下文放到Perl对象中。