修复CC项目的ldquo未
本教程说明如何解决与C/C++项目中缺少符号有关的各种问题。我们将创建一个基本项目,从libpng库中调用png_create_read_struct()函数,并将执行常见的缺少设置步骤,解释将出现的错误。
在开始之前,请安装VisualGDB5.4或更高版本。
1.启动VisualStudio并找到VisualGDBLinuxProjectWizard:
2.选择项目的名称和位置:
3.按“Create”以启动向导中特定于VisualGDB的部分。在第一页上,选择“Createanewproject-Application-MSBuild”:
4.在本教程中,我们将使用在Windows上运行并为Linux目标构建代码的跨工具链,并将演示此配置导致的故障点。但是,下面显示的大多数步骤也适用于直接在Linux上构建的项目:
5.按“Finish”以生成项目。现在,我们将尝试从libpng库中调用一个函数,并将执行可能会导致构建时或运行时错误的大多数可能丢失的步骤。将以下代码添加到main()函数,然后尝试构建项目:
png_create_read_struct(NULL,NULL,NULL,NULL);
6.现在,构建将因以下错误而失败:
MissingSymbolDemo.cpp:Infunctionintmain(int,char**):
MissingSymbolDemo.cpp:7:5:error:png_create_read_structwasnotdeclaredinthisscope
png_create_read_struct(NULL,NULL,NULL,NULL);
^~~~~~~~~~~~~~~~~~~~~~
7.您可以通过右键单击错误消息并选择“GotoBuildLog”来找到GCC的确切输出:
8.错误“png_create_read_struct’wasnotdeclaredinthisscope”,表示C/C++编译器不知道png_create_read_struct符号。它无法确定它是函数,全局函数指针还是预处理器宏。要解决此错误,需要声明png_create_read_struct()函数。声明如下:
png_structppng_create_read_struct(png_const_charpuser_png_ver,png_voidperror_ptr,png_error_ptrerror_fn,png_error_ptrwarn_fn);
9.由于将每个函数声明复制到每个源文件中是不切实际的,因此大多数C/C++库都提供列出所有相关声明的头文件。通常,您可以在文档中找到头文件名,并将其包含在程序中,如下所示:
#includepng.h
这等同于将头文件内容复制并粘贴到源文件中。
10.包含头文件将不会在整个构建机器中搜索它。相反,GCC将仅搜索几个常见位置(例如/usr/include),并且在项目设置中指定头搜索目录。在我们的示例中,png.h文件位于工具链的/usr/include/libpng目录中,最初不会被找到,从而产生以下错误:
MissingSymbolDemo.cpp:2:10:fatalerror:png.h:Nosuchfileordirectory
#includepng.h
^~~~~~~
11.VisualGDB通常会在附近目录中搜索缺少的标头,并建议自动修复设置。如果您是手动配置项目,则只需在构建计算机上找到头文件,然后将其目录添加到“IncludeDirectories”字段中即可:
请注意,如果您使用的是跨工具链,则该头文件必须位于其sysroot目录中(例如/usr/include/libpng/png.h对应于E:\sysgcc\raspberry\arm-linux-gnueabihf\sysroot\usr\include\libpng\png.h)。如果使用的是在Windows上运行的跨工具链,则需要指定Windows计算机上文件的路径(即$(ToolchainDir)\arm-linux-gnueabihf\sysroot\usr\include\libpng\png。H)。为了方便起见,GCC会自动用sysroot目录替换路径开头的“=”,因此本示例中正确的包含目录应为=/usr/include/libpng/png.h(请注意开头的“=”)。
12.如果您现在构建项目,它将失败并出现另一个错误:
C:\projects\temp\MissingSymbolDemo/MissingSymbolDemo.cpp:9:undefinedreferenceto`png_create_read_struct
Buildfailed:arm-linux-gnueabihf-g++.exeexitedwithcode1
collect2.exe:error:ldreturned1exitstatus
13.发生这种情况是因为png.h文件仅包含png_create_read_struct()函数的声明。即,它定义了它的返回类型和参数类型(让GCC在编译时检查它们),但是它没有提供实现。函数实现通常位于静态库(.a文件)或共享库(.so文件)中。通过搜索所有包含png_create_read_struct文本的.a和.so文件,可以找到正确的库名称。如果找到了几个库,请使用objdump-T.sofile或objdump-t.afile命令列出该库导出的所有符号:
e8fcgDF.text0024PNG16_0png_create_read_struct
如果您要查找的符号列出的地址非零(第一列),则说明您找到了正确的库。否则,该库将导入该符号,而不是将其导出。
14.在此示例中,定义png_create_read_struct()的库称为libpng.so。您可以通过将其名称(不带lib前缀)添加到“LibraryNames”字段中来链接到您的项目,只要它位于标准库目录中即可。如果没有,您还需要将库目录添加到“LibraryDirectories”字段中:
15.现在您可以成功构建项目:
如果构建仍然失败,则可能在标头中缺少extern“C”子句。
16.最后,我们将演示运行时错误。将构建的程序部署到目标并运行“ldBinaryName”:
17.LDD命令将显示该文件所需的共享库。在本教程中,我们将所有libpng*库移动到/usr/lib/arm-linux-gnueabihf/png子目录,并显示将发生的情况。移动库后,开始使用VisualGDB调试项目,并在“DebugOutput”中观察以下错误消息:
/tmp/MissingSymbolDemo:errorwhileloadingsharedlibraries:libpng16.so.16:cannotopensharedobjectfile:Nosuchfileordirectory
VisualGDB会自动建议在目标上定位文件:
18.在移动目录libpng16.so中找到它,然后按“OK”:
19.这将自动将库的目录添加到项目的LD_LIBRARY_PATH变量中,因此现在您将能够成功启动它:
20.如果您是手动运行项目,只需将缺少的.so文件的目录添加到LD_LIBRARY_PATH变量中(如下所示),就可以对其进行处理:
由于我们已将NULL传递给png_create_read_struct()而不是libpng版本数字,它将显示警告消息。您可以通过将PNG_LIBPNG_VER_STRING作为第一个参数传递给png_create_read_struct()来消除它。
VisualGDB使使用VisualStudio的跨平台开发变得轻松而舒适
预览时标签不可点收录于话题#个上一篇下一篇转载请注明:http://www.imbnc.com/mlyhl/12416.html
- 上一篇文章: 基督作为上帝代表的荣耀
- 下一篇文章: 刚刚又一地升级为中风险