如何在 XS 中编写 Perl 构造函数?

发布于 2024-08-06 17:04:54 字数 209 浏览 7 评论 0原文

我正在尝试为 Perl 编写新的 XS 模块。我已经按照 XS 模块编写指令进行了测试,并且工作正常。

我无法理解如何为 XS 编写 new 方法,

我有一个名为 Agent 的包。我希望能够做到这样的事情:

my $agent_object = new Agent;

I am trying to write new XS module for Perl. I have tested by following XS module writing instruction and it is working fine.

I am not able to understand how to I write new method for XS

I have a package called Agent. I want to be able to something like this:

my $agent_object = new Agent;

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

柒七 2024-08-13 17:04:54

我从 XS Mechanics 得到了答案。

感谢您的帮助

I got the answer from XS Mechanics.

Thanks For your help

瑾兮 2024-08-13 17:04:54

以下代码实现了

sub new {
  my $class = shift;
  return bless {@_} => $class;
}

XS 中的典型构造函数。它是从 Class::XSAccessor 逐字复制的。我建议您在使用普通的基于哈希的对象时调查 Class::XSAccessor 的情况。无需重新发明这个轮子。

void
new(class, ...)
    SV* class;
  PREINIT:
    unsigned int iStack;
    HV* hash;
    SV* obj;
    const char* classname;
  PPCODE:
    if (sv_isobject(class)) {
      classname = sv_reftype(SvRV(class), 1);
    }
    else {
      if (!SvPOK(class))
        croak("Need an object or class name as first argument to the constructor.");
      classname = SvPV_nolen(class);
    }

    hash = (HV *)sv_2mortal((SV *)newHV());
    obj = sv_bless( newRV((SV*)hash), gv_stashpv(classname, 1) );

    if (items > 1) {
      if (!(items % 2))
        croak("Uneven number of argument to constructor.");

      for (iStack = 1; iStack < items; iStack += 2) {
        hv_store_ent(hash, ST(iStack), newSVsv(ST(iStack+1)), 0);
      }
    }
    XPUSHs(sv_2mortal(obj));

The following code implements a typical

sub new {
  my $class = shift;
  return bless {@_} => $class;
}

constructor in XS. It's copied verbatim from Class::XSAccessor. I would suggest you investigate Class::XSAccessor for cases when you are using an ordinary hash based object. No need to reinvent this wheel.

void
new(class, ...)
    SV* class;
  PREINIT:
    unsigned int iStack;
    HV* hash;
    SV* obj;
    const char* classname;
  PPCODE:
    if (sv_isobject(class)) {
      classname = sv_reftype(SvRV(class), 1);
    }
    else {
      if (!SvPOK(class))
        croak("Need an object or class name as first argument to the constructor.");
      classname = SvPV_nolen(class);
    }

    hash = (HV *)sv_2mortal((SV *)newHV());
    obj = sv_bless( newRV((SV*)hash), gv_stashpv(classname, 1) );

    if (items > 1) {
      if (!(items % 2))
        croak("Uneven number of argument to constructor.");

      for (iStack = 1; iStack < items; iStack += 2) {
        hv_store_ent(hash, ST(iStack), newSVsv(ST(iStack+1)), 0);
      }
    }
    XPUSHs(sv_2mortal(obj));
忆梦 2024-08-13 17:04:54

如果您的 Agent.xs 包含:

class Agent {
public:
  Agent() {
    // constructor stuff
  }

当您说 Agent->new 时,XS 不会自动调用该构造函数吗?

If your Agent.xs contains:

class Agent {
public:
  Agent() {
    // constructor stuff
  }

doesn't XS call that constructor automatically when you say Agent->new?

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文