I was stuck on a similar sort of problem recently, and it took a while to figure out what to do. After much re-reading
of: "perldoc (perlembed, perlcall, perlguts, perlapi)" and
some trial and error coding (time-wasting), I came
up with something that looks like the following code, which
I hope will save you some time (there are probably some
problems in it but the gist of it should be helpful):
int getStringFromPerlSubroutine(PerlInterpreter* perlInterpreter, char
+* packageExplicitSubName, SV** string)
{
PERL_SET_CONTEXT(perlInterpreter);
dSP; // Initialize local st
+ack pointer everything created after here.
ENTER;
SAVETMPS; // This is a temporary
+ variable.
PUSHMARK(SP); // Remember the stack
+pointer.
PUTBACK; // Make local the stac
+k pointer global.
if (call_pv(packageExplicitSubName, G_SCALAR | G_NOARGS | G_EV
+AL) == 0) {
// TODO: Interpret return value for success.
//fprintf(stderr, "Error: call_pv did not return 1 as
+it should have. \n");
//return 1;
}
SPAGAIN; // Refresh the stack p
+ointer.
// Check there were no problems in the subroutine.
if (SvTRUE(ERRSV)) {
STRLEN n_a;
fprintf(stderr, "Error: getSvPV %s. \n", SvPV(ERRSV, n
+_a));
POPs;
return 1;
}
STRLEN n_a;
SV* stringRV = newRV_inc(POPs);
// Check returned SV is a reference.
if (!SvROK(stringRV)) {
fprintf(stderr, "Error: getSvPV could not get a refere
+nce to the SVt_PV expected to be returned by the Perl subroutine. \n"
+);
return 1;
}
// Check the type of the reference
if (SvTYPE(SvRV(stringRV)) != SVt_PV) {
fprintf(stderr, "Error: getSvPV was not returned a ref
+erence to an SVt_PV from the Perl subroutine as expected. (Actual enu
+m: %d) \n",
SvTYPE(SvRV(stringRV)) );
return 1;
}
*string = SvRV(stringRV);
//printf("%s \n", SvPV(tempPV, n_a));
//*string = SV* stringSV = newSVpx(POPpx, n_a);
//printf("Inside %s \n", SvPV(*string, n_a));
//(*string->sv_refcnt)++;
PUTBACK;
FREETMPS; // Free that return va
+lue.
LEAVE; // Free the XPUSHed "m
+ortal" args.
return 0;
}
int main()
{
PerlInterpreter *perlInterpreter;
//Init perlInt...
STRLEN len;
SV* string = newSV(sizeof(SV*));
getStringFromPerlSubroutine(perlInterpreter, "TestPackage::getString"
+, &string);
printf("%s \n", SvPV(string, len));
printf("Length of returned string: %d", len);
SvREFCNT_dec(string);
// Cleanup perlInt...
return 0;
}
| [reply] [d/l] |