in reply to Re^2: C++ strings, references and XS (char*)
in thread C++ strings, references and XS

the problem is that I don't know how would that affect memory handling

That is why I said (emphasis added):

or grab output.c_str() for the XS to copy into the returned PV for the other

You write a C++ function that has a lexical std::string that it passes to the method for the method to fill in. Then you copy the value from output.c_str() to a Perl PV (part of an SV). The handling of a RETVAL of type "char*" will do this copying automatically.

I suppose it becomes a problem if you can't get the XS code to be treated as C++ such that the XS routine is where you declare the output std::string. Though I'm pretty sure this is possible, I also realize that it at least used to be somewhat difficult, requiring some undocumented fiddling.

If I wanted to avoid that complication, then I'd have the middle-man C++ function take two input "char*"s (still) and one output SV* (see your typemap file for the simple incantation required to copy a '\0'-terminated "char*" into the PV of an SV).

- tye        

  • Comment on Re^3: C++ strings, references and XS (char*)

Replies are listed 'Best First'.
Re^4: C++ strings, references and XS (char*)
by v01d (Novice) on Dec 20, 2005 at 21:58 UTC

    I'm sorry for misreading your answer (not enough caffeine).

    I tried what I understood from you response and... it works! Thanks a lot for helping me. For any other person out there the xs that made it work was (note that the substantial changes are in the respond function, the rest was just because there was no more need to use the derived class):

    #ifdef __cplusplus extern "C" { #endif #include "EXTERN.h" #include "perl.h" #include "XSUB.h" #include "ppport.h" #ifdef __cplusplus } #endif #include <string> #include <libaiml/core.h> using std::string; using aiml::cCore; using aiml::AIMLError; MODULE = AI::AIML PACKAGE = AI::AIML cCore * cCore::new() void cCore::DESTROY() bool cCore::initialize(const char* file) void cCore::deinitialize() long cCore::get_error() const char* cCore::get_error_str(AIMLError error_num); const char* cCore::respond(const char* input, const char* username) CODE: string out; if (!THIS->respond(input, username, out)) XSRETURN_UNDEF; else RETVAL = out.c_str(); OUTPUT: RETVAL

    I obviously also changed the typemap accordingly (cAiml -> cCore).

    Don't know if you know what AIML is (you can google that), but if you do, you may understand my happiness when I read this:

    PERL_DL_NONLAZY=1 /usr/bin/perl5.8.6 "-MExtUtils::Command::MM" "-e" "t +est_harness(0, 'blib/lib', 'blib/arch')" t/*.t t/AI-AIML....ok 3/4# Returned: Hello there. + t/AI-AIML....ok + All tests successful. Files=1, Tests=4, 8 wallclock secs ( 7.48 cusr + 0.16 csys = 7.64 C +PU)
    (notice the "Returned", as an aswer to "hi") =] Thanks a lot.