添加链接
link之家
链接快照平台
  • 输入网页链接,自动生成快照
  • 标签化管理网页链接

当链接动态库时出现下面这样的错误时,一般是动态库生成的编译选项问题

found local symbol '__bss_start' in global part of symbol table
found local symbol '_edata' in global part of symbol table
found local symbol '_end' in global part of symbol table 

解决方法:

Android.mk ::     APP_LDFLAGS := -fuse-ld=gold

CMakeLists.txt:

/home/user/cmake-3.12.1/bin/cmake -DCMAKE_SHARED_LINKER_FLAGS=-fuse-ld=gold .. -DANDROID_ABI=arm64-v8a 后面省略了

查看确认方法:readelf -s *.so |grep "__bss_start"

参考链接:

https://stackoverflow.com/questions/55014879/local-symbol-bss-start-in-global-part-of-symbol-table-only-in-android-ndk

当链接动态库时出现下面这样的错误时,一般是动态库生成的编译选项问题found local symbol '__bss_start' in global part of symbol tablefound local symbol '_edata' in global part of symbol tablefound local symbol '_end' in global par... 如何使用dlopen API动态地加载C++函数和类,是Unix C++程序员经常碰到的 问题 。 事实上,情况偶尔有些复杂,需要一些解释。这正是写这篇mini HOWTO的缘由。 理解这篇文档的前提是对C/C++语言中dlopen API有基本的了解。 这篇HOWTO的维护链接是: http://www.isotton.com/howtos/C++-dlopen-mini-HOWTO/ 二、 问题 所在 有时你想在运行时加载一个库(并使用其中的函数),这在你为你的程序写一些插件或模块架构的时候经常发生。 在C语言中,加载一个库轻而易举(调用dlopen、dlsym和dlclose就够了),但对C++来说,情况稍微复杂。 动态加载一个C++库的困难一部分是因为C++的name mangling (译者注:也有人把它翻译为“名字毁坏”,我觉得还是不翻译好), 另一部分是因为dlopen API是用C语言实现的,因而没有提供一个合适的方式来装载类。 在解释如何装载C++库之前,最好再详细了解一下name mangling。 我推荐您了解一下它,即使您对它不感兴趣。因为这有助于您理解 问题 是如何产生的,如何才能解决它们。 1. Name Mangling 在每个C++程序(或库、目标文件)中, 所有非静态(non-static)函数在二进制文件中都是以“符号(symbol)”形式出现的。 这些符号都是唯一的字符串,从而把各个函数在程序、库、目标文件中区分开来。 在C中,符号名正是函数名:strcpy函数的符号名就是“strcpy”,等等。 这可能是因为两个非静态函数的名字一定各不相同的缘故。 而C++允许重载(不同的函数有相同的名字但不同的参数), 并且有很多C所没有的特性──比如类、成员函数、异常说明──几乎不可能直接用函数名作符号名。 为了解决这个 问题 ,C++采用了所谓的name mangling。它把函数名和一些信息(如参数数量和大小)杂糅在一起, 改造成奇形怪状,只有编译器才懂的符号名。 例如,被mangle后的foo可能看起来像foo@4%6^,或者,符号名里头甚至不包括“foo”。 其中一个 问题 是,C++标准(目前是[ISO14882])并没有定义名字必须如何被mangle, 所以每个编译器都按自己的方式来进行name mangling。 有些编译器甚至在不同版本间更换mangling算法(尤其是g++ 2.x和3.x)。 即使您搞清楚了您的编译器到底怎么进行mangling的,从而可以用dlsym调用函数了, 但可能仅仅限于您手头的这个编译器而已,而无法在下一版编译器下工作。 使用dlopen API的另一个 问题 是,它只支持加载函数。 但在C++中,您可能要用到库中的一个类,而这需要创建该类的一个实例,这不容易做到。 四、解决方案 1. extern "C" C++有个特定的关键字用来声明采用C binding的函数: extern "C" 。 用 extern "C"声明的函数将使用函数名作符号名,就像C函数一样。 因此,只有非成员函数才能被声明为extern "C",并且不能被重载。 尽管限制多多,extern "C"函数还是非常有用,因为它们可以象C函数一样被dlopen动态加载。 冠以extern "C"限定符后,并不意味着函数中无法使用C++代码了, 相反,它仍然是一个完全的C++函数,可以使用任何C++特性和各种类型的参数。
在用AndroidStudio开发APP时,因重新拉取git仓库代码,导致以下错误: [164/164] Linking CXX shared library ..\..\..\..\build\intermediates\cmake\debug\obj\arm64-v8a\libailiving.so FAILED: cmd.exe /C "cd . && C:\Users\LENOVO\App Data \Local\Android\Sdk\ndk\22.1.7171670\toolcha
类型选择dll 2. IDE自动生成的代码已经把整个架构弄好了,其中和项目同名的.h和.cpp文件就是我们自己写代码的地方了。我想写的dll是导出一个类,在这里我就直接在它自动生成的CmyDll类上面改了。 myDll.h myDll.cpp 在mydll.h和mydll.cpp中给类添加成员函数 //mydll.h class MYDLL_API CmyDll { public: CmyDll(void); // TODO: 在此添加您的方法。 int myFunction(int a, int b); //mydll.cpp int CmyDll::myFunction(int a, int b) { return a*b; 3.编译的时候我选择了release,这里可以用默认的debug也行 在mydll.h和mydll.cpp中给类添加成员函数 最后生成解决方案后产生的mydll.lib和mydll.dll就是我们需要的二进制文件了。lib文件是编译是要用的,而dll是调用这个库的程序运行时需要的。 调用dll 1.重新建立一个工程 这回选择普通的控制台程序就行了。我建了个名为myDllCall的工程。 2.把库的头文件include进来,以及连接lib文件 其中 include进来的 myDll.h 和 **#pragma comment()**的lib根据自己的路径写。 #include "stdafx.h" #include "../../myDll/myDll/myDll.h" //头文件 #pragma comment(lib,"../../myDll/Release/myDll.lib") //调用自己写的外部库 #include int main() CmyDll mydll; int a, b; std::cin >> a >> b; std::cout << mydll.myFunction(a, b) <> a >> b; std::cout << mydll.myFunction(a, b) << std:: end l; return 0; 3.dll放到可执行文件同一目录下面 刚刚的代码直接编译没 问题 ,运行会报错. 直接编译没 问题 ,运行会报错 原因是dll要和生成的可执行文件在同一个目录下,我把mydll.dll放进去之后就解决了。 我们成功的在自己的工程里调用了外部的类 可以看到我们成功的在自己的工程里调用了外部的类。 Gradle sync failed: com.android.tools.idea.gradle.project.sync.idea.issues.SdkPlatformNotFoundException: Module: ‘ble data control’ platform ‘android-24’ not found. (12 s 199 ms) sdk版本不对应 下载对应的sdk java.lang.ClassNotFoundExce
在centos上装了两个版本的gcc,4.8和7.3,编译程序遇到链接 问题 。找不到xx的引用。“undefined reference to ...”。明明刚才编译出来的库一链接就是找不到符号。 找不到符号那就先查看一下动态(静态)链接库的符号。用命令 nm -g libcryptopp-arm64.a | c++filt | grep BufferedTransformation::Chan...
静态链接中有一个专门的段叫 符号表 -- “.symtab”(Symbol Table),里面保存了所有关于该目标文件的符号的定义和引用。 动态链接中同样有一个段叫 动态 符号表 -- “.dynsym”(Dynamic Symbol) , 但.dynsym 相对于 .symtab 只保存了与动态链接相关的导入导出符号。 so中同样有.symtab,其中保存着所有的符号 .symt...
2. 使用gcc编译器将源代码文件编译成目标文件,例如test.o。 3. 使用gcc编译器将目标文件链接成 动态链接库 ,例如libtest.so。在链接时需要使用共享库选项“-shared”。 4. 将生成的 动态链接库 复制到系统库路径中,例如/usr/lib。 5. 在需要使用 动态链接库 的程序中,使用“-l库名”选项来链接 动态链接库 ,例如gcc -o main main.c -ltest。 6. 运行程序, 动态链接库 会在运行时被加载并链接。 需要注意的是,在编写源代码文件时需要使用导出函数的方式来定义 动态链接库 的接口,例如使用“__attribute__((visibility("default")))”来声明函数可见性。同时,还需要注意 动态链接库 的版本号和 符号表 问题 ,以确保 动态链接库 的兼容性和稳定性。