标题很难做到,所以让我解释一下我的情况:
另一个团队开发了一个图书馆。他们发送头文件和*.so
文件。头文件可供我们使用,我们可以将其包含在我们自己的代码中,并在我们希望的情况下使用它。但是,*.so
随我们运行的平台一起提供。我们的软件在构建时无法访问此*.so
。因此,我们也无法真正使用头文件,因为链接器会期望*.so
在某些时候可用。
现在我要做的是创建一个在运行时加载*.so
文件的包装类,然后使用dlsym()
按名称查找函数,并将它们映射到函数指针。
这是唯一的选择吗?有没有办法可以使用头文件但是告诉链接器在构建时不解析符号,而是在我们有机会加载*.so
文件之后尝试在运行时解析它们?
请注意,这里的真实平台是Android(通过NDK),但希望一般的Linux建议在这种情况下也能正常工作,因为我们有POSIX API可用。
答案 0 :(得分:1)
在Windows上,这可以通过要求链接器而不是真实动态库(.dll)的导出库(.lib)来解决。我认为你可以尝试制作类似的东西,即制作一个假的.so包含从真实.so导出的所有方法的存根并链接它。这有望使链接器满意,同时在运行时应用程序将加载真正的.so。
答案 1 :(得分:1)
您可以按优先顺序选择一些选项:
int foo; void bar() {}
放在C文件中,以获取需要公开的所有变量和函数,并将其构建为共享库。如果您在版本脚本中包含符号列表,则可以使用Android gen_stub_libs.py为您执行此操作。__attribute__((weak))
的所有符号。链接者不会抱怨他们失踪了。如果它们在运行时丢失,则库仍将加载,但每个函数的地址将为nullptr
。在大多数情况下,实际上并不是您想要的,因为如果您对库的定义错误,则会将构建时失败转变为运行时失败,但在某些情况下,这可能很方便,因为使用{{更容易检查函数可用性1}}然后与if (foo) { foo(); }
类似。dlsym
添加到您的ldflags中。这甚至比3更差,因为它会影响您链接的所有库,但它不会要求您插入标题。