开发者

Updated: When to "mortalize" a variable in Perl Inline::C

开发者 https://www.devze.com 2023-02-14 15:34 出处:网络
I am trying to wrap a C library into Perl. I have tinkered with XS but being unsuccessful I thought I should start simply with Inline::C. My question is on Mortalization. I have been reading perlguts

I am trying to wrap a C library into Perl. I have tinkered with XS but being unsuccessful I thought I should start simply with Inline::C. My question is on Mortalization. I have been reading perlguts as best as I am able, but am still confused. Do I need to call sv_2mortal on an SV* that is to be returned if I am not pushing it onto the stack?

(PS I really am working on a less than functional knowledge of C which is hurting me. I have a friend who knows C helping me, but he doesn't know any Perl).

I am providing a sample below. The function FLIGetLibVersion simply puts len characters of the library version onto char* ver. My question is will the version_return form of my C code leak memory?

N.B. any other comments on this code is welcomed.

#!/usr/bin/perl

use strict;
use warnings;

use 5.10.1;

use Inline (
  C => 'DATA',
  LIBS => '-lm -lfli',
  FORCE_BUILD => 1,
);

say version_stack();
say version_return();

__DATA__
__C__

#include <stdio.h>

#include "libfli.h"

void version_stack() {

  Inline_Stack_Vars;
  Inline_Stack_Reset;

  size_t len = 50;
  char ver[len];

  FLIGetLibVersion(ver, len);

  Inline_Stack_Push(sv_2mortal(newSVpv(ver,strlen(ver))));
  Inline_Stack_Done;

}

SV* version_return() {

  size_t len = 50;
  char ver[len];

  FLIGetLibVersion(ver, len);
  SV* ret = newSVpv(ver, strlen(ver));

  return ret;

}

Edit:

In an attempt to answer this myself, I tried changing the line to

SV* ret = sv_2mortal(newSVpv(ver, strlen(ver)));

and now when I run the script I get the same output that I did previously plus an extra warning. Here is the output:

Software Development Library for Linux 1.99
Software Development Library for Linux 1.99
Att开发者_开发知识库empt to free unreferenced scalar: SV 0x2308aa8, Perl interpreter: 0x22cb010.

I imagine that this means that I don't need to mortalize in this case? I suspect that the error is saying that I marked for collection something that was already in line for collection. Can someone confirm for me that that is what that warning means?


I've been maintaining Set::Object for many years and had this question, too - perhaps best to look at the source of that code to see when stuff should be mortalised (github.com/samv/Set-Object). I know Set::Object has it right after many changes. I think though, it's whenever you're pushing the SV onto the return stack. Not sure how Inline changes all that.

0

精彩评论

暂无评论...
验证码 换一张
取 消