问题
I have two libraries, I want to call routines in the first library, they then call routines in the second library, but crash because those symbols are undefined. Is it possible to say "load these symbols" from library XX even though I don't want to call them?
testlib1.c:
#include <stdio.h>
void sub2();
void sub1() {
printf("Called sub1\n");
sub2();
}
testlib2.c:
#include <stdio.h>
void sub2() {
printf("Called sub2\n");
}
testit.p6:
use NativeCall;
sub sub1() is native('testlib1') {}
sub sub2() is native('testlib2') {}
sub1();
error:
Cannot locate native library 'libtestlib1.so': ./libtestlib1.so: undefined symbol: sub2
If I call sub2
manually before calling sub1
, it works fine, but I don't want to do that..
回答1:
This might be a bit naive, but shouldn't the problem be solved at the C or linker level rather than the Perl 6 level? I mean, even in the C code, sub1
won't work. Why would you expect a higher level (Perl 6) to fix the problems of the lower-level code?
回答2:
Ok, This makes it work, but is a non-portable workaround -- it only works if your MoarVM is built with dyncall
. It seems like there should be some exposed function to NativeCall
world that does this portably.
use NativeCall;
sub dlLoadLibrary(Str --> Pointer) is native {}
dlLoadLibrary('libtestlib2.so');
sub sub1() is native('testlib1') {}
sub1();
dlLoadLibrary
is the dyncall
way to load a dynamic library, which is apparently enough for the symbol to be resolved.
Better suggestion from @jnthn:
sub fake() is native('testlib2');
try fake();
fake()
loads testlib2
, throws an Exception
because fake
isn't a real routine in that library, but try
ignores the Exception
.
来源:https://stackoverflow.com/questions/49036300/nativecall-loading-a-library-symbol-i-dont-call