NativeCall加载我不调用的库符号

时间:2018-02-28 18:33:08

标签: perl6 nativecall

我有两个库,我想在第一个库中调用例程,然后在第二个库中调用例程,但是因为这些符号未定义而崩溃。即使我不想打电话给它们,是否可以从库XX中说“加载这些符号”?

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();

错误:

Cannot locate native library 'libtestlib1.so': ./libtestlib1.so: undefined symbol: sub2

如果我在致电sub2之前手动拨打sub1,它可以正常工作,但我不想这样做..

2 个答案:

答案 0 :(得分:2)

好的,这可以使用它,但它是一种非便携式解决方法 - 只有在MoarVM使用dyncall构建时才有效。看起来NativeCall世界应该有一些暴露的功能可以这样做。

use NativeCall;                                                                 

sub dlLoadLibrary(Str --> Pointer) is native {}                                 
dlLoadLibrary('libtestlib2.so');                                                

sub sub1() is native('testlib1') {}                                             

sub1();                                                                         

dlLoadLibrary是加载动态库的dyncall方式,显然足以解析符号。

来自@jnthn的更好的建议:

sub fake() is native('testlib2');
try fake();

fake()加载testlib2,抛出Exception,因为fake不是该库中的真实例程,但try忽略Exception }。

答案 1 :(得分:2)

这可能有点天真,但问题不应该在C或链接器级而不是Perl 6级解决?我的意思是,即使在C代码中,sub1也无效。为什么你期望更高级别(Perl 6)来修复低级代码的问题?