Question

I am working with Perl embedded in our application. We have installed quite a few C++ functions that are called from within Perl. One of them is a logging function. I would like to add the file name and line number of the Perl file that called this function to the log message.
I know on the Perl side I can use the "caller()" function to get this information, but this function is already used in hundreds of locations, so I would prefer to modify the C++ side, is this information passed to the C++ XSUB functions and if so how would I get at it?

Thanks.

Was it helpful?

Solution

This should work:

char *file;
I32 line;

file = OutCopFILE(PL_curcop);
line = CopLINE(PL_curcop);

Control ops (cops) are one of the two ops OP_NEXTSTATE and op_DBSTATE, that (loosely speaking) are separate statements. They hold information important for lexical state and error reporting. At run time, PL_curcop is set to point to the most recently executed cop, and thus can be used to determine our current state.

— cop.h

OTHER TIPS

Can't you call perl builtins from XS? I confess I don't know.

If not, you could always do something like this:

sub logger { _real_logger(caller, @_) }

assuming logger is what your function is called (and you rename your C++ XS function to _real_logger. You could also do this, presumably, if you need to hide yourself in the call tree:

sub logger {
    unshift @_, caller;
    goto &_real_logger;
}

which is of course the normal form of goto used in AUTOLOAD.

These will add overhead, of course, but probably not a big deal for a logging function.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top