首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

一个奇怪的链接问题

前言 链接是代码生成可执行文件中一个非常重要的过程。我们在使用一些库函数时,有时候需要链接库,有时候又不需要,这是为什么呢?了解一些链接的基本过程,能够帮助我们在编译时解决一些疑难问题。...‘main’中: expTest.c:(.text+0x20):对‘exp’未定义的引用 collect2: error: ld returned 1 exit status 我们发现,同样的编译方法编译不过了...,提示对‘exp’未定义的引用,并且抛出链接出错。...再次编译运行: gcc -lm -o expTest expTest.c /tmp/ccYT3E65.o:在函数‘main’中: expTest.c:(.text+0x20):对‘exp’未定义的引用...这个就涉及到链接器的工作原理了,在此只简单说明一下:链接过程中,需要进行符号解析,并且是按照顺序解析;如果库链接在前,就可能出现库中的符号不会被需要,链接器不会把它加到未解析的符号集合中,那么后面引用这个符号的目标文件就不能解析该引用

1.6K20
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    LNK2019 无法解析的外部符号 WinMain,该符号在函数 int __cdecl invoke_main(void) (?invoke_main@@YAHXZ) 中被引用

    ,那么main是入口函数,在VS中新建项目为“win32控制台应用程序” 而如果入口函数指定不当,很显然c语言运行时找不到配合函数,它就会报告错误。...程序,略 若这两项配置是对的,然依然有这个问题,问题在于,如果是MFC项目的话 需要在属性\常规\MFC的使用 中 要选择 【在静态库中使用MFC】 若是win32的话则选择【使用标准windows库】...C++->Preprocessor,然后在右边栏的Preprocessor Definitions对应的项中删除_WINDOWS, 添加_CONSOLE. 3.在左边栏中依次选择:Configuration...(主函数); 反之也一样,创建项目时,选择了win32项目,而把代码当win32控制程序写了,即代码里面使用main()做为函数入口(主函数); 所以出现了以上报错,意思就是主函数和当前项目不匹配。...2.如果你选了MFC项目,就按照方法三那位兄台说的:   若这两项配置是对的,然依然有这个问题,问题在于,如果是MFC项目的话 需要在属性\常规\MFC的使用 中 要选择 【在静态库中使用MFC】

    17.2K51

    QT使用windowsAPI函数提示error LNK2019: 无法解析的外部符号 该符号在函数 _main 中被引用解决方案

    在使用windowsAPI函数的过程中,已经加入了头文件,但是依旧会报error LNK2019: 无法解析的外部符号该符号在函数 _main 中被引用,我以前也用过...API,但是没有出现此问题,最后的解决方案是只需要在pro文件下面加入win32:LIBS += -luser32即可解决问题。...查了半天资料,在qt中调用Windows API函数有时需要自己关联系统库时,不仅仅需要相关的头文件,有些还需要自己关联系统库,就想SystemParametersInfoA()这个函数这样;但是有些系统函数在...打开MSDN,右上角输入这个函数,拉到最下面。 参考博文:Qt调用头文件setupapi.h的函数SetupDiGetClassDevs()编译出错

    3.9K20

    完美解决丨#在python中,如果引用的变量未定义,则会报告NameError: name ‘变量名‘ is not defined。

    NameError 在python中,如果引用的变量未定义,则会报告NameError: name '变量名' is not defined。 如下代码抛出了一个异常: !...提示: 一般来说,在python中,需要保证变量的定义在使用的前面。...IndexError 在python中,如果list、tuple中的元素被引用的索引值超过了元素的个数,则会报告IndexError: list index out of range。...原因: list的索引值超过了list元素的个数。 KeyError 在python中,如果dict中的key不存在,则会报告KeyError: 'key'。 如下代码抛出了一个异常: !...原因: dict中不存在address这个key。 TypeError 在python中,如果一个对象不是内置对象的实例,则会报告TypeError。 如下代码抛出了一个异常: !

    2.9K10

    Linux命令(65)——ld命令

    -b :指定目标代码输入文件的格式 -Bstatic:只使用静态库 -Bdynamic:只使用动态库 -Bsymbolic:把引用捆绑到共享库中的全局符号 -c 的效果 -defsym:在输出文件中创建指定的全局符号 -demangle:在错误消息中还原符号名称 -e :使用指定的符号作为程序的初始执行点.../写入文本和数据段 -n,--nmagic: 关闭节的页面对齐,并禁用对共享库的链接。...size默认为1 -split-by-reloc[=count]:按照指定的长度在输出文件中创建额外的段 --section-start==:在输出文件中指定的地址定位指定的段...org>:使用指定的地址作为bss段的起始点 -t,--trace:在处理输入文件时显示它们的名称 -u ,--undefined=:强制指定符号在输出文件中作为未定义符号

    17.7K13

    Hello World背后的故事:如何在Linux上编译C语言程序

    接着,int main()定义了主函数,是这个程序的入口。main()方法的返回值是int,在本程序中,我们返回了0,0表示程序正常结束,非0的结果表示程序异常结束。...在x86_64架构中,printf()方法在底层是用call puts来实现的,call用来调用一个函数。...puts函数只出现了一个名字,它是C标准库里定义的函数,具体的实现并没有在上面这个程序中定义。...如果提示crt1.o这几个文件找不到,可以使用find命令来查找: $ find /usr/lib -name 'crt1.o' 我们知道,main()方法是C语言程序的入口,crt1.o这几个库是在处理...另外,增加了_start,_start是程序的真正入口,在_start中会进行初始化等工作。

    1.9K11

    c语言中static关键字用法详解

    全局变量 全局变量定义在函数体外部,在全局数据区分配存储空间,且编译器会自动对其初始化。 普通全局变量对整个工程可见,其他文件可以使用extern外部声明后直接使用。...其特性如下: 静态函数只能在声明它的文件中可见,其他文件不能引用该函数 不同的文件可以使用相同名字的静态函数,互不影响 非静态函数可以在另一个文件中直接引用,甚至不必使用extern声明 下面两个文件的例子说明使用...\n"); } 使用 gcc file1.c file2.c编译时,错误报告如下: /tmp/cc2VMzGR.o:在函数‘main’中: static_fun.c:(.text+0x20):对‘fun1...’未定义的引用 collect2: error: ld returned 1 exit status 修改文件,不使用static修饰符,可在另一文件中引用该函数: /* file1.c */ #include...其特点如下: 静态数据成员存储在全局数据区,静态数据成员在定义时分配存储空间,所以不能在类声明中定义 静态数据成员是类的成员,无论定义了多少个类的对象,静态数据成员的拷贝只有一个,且对该类的所有对象可见

    75120

    从程序员角度看ELF

    可执行文件,他们的入口点都是 _start,   然后由 _start 函数调用 _init 执行相关的 .init 节中的初始化代码!...see 启动过程::共享库的初始化)   而dlopen 一个 .so 共享库后,_init 函数在返回前会被调用,.so 共享库   是没有 _start 的!   ...R_386_32:对在另一个库中定义的符号的非GOT引用,通常是静态数据区中的指针。   ...R_386_RELATIVE:对可重定位数据的引用,典型的是指向字串(或其它局部定义静态数   据)的指针。   ...静态的初始化   如果一个程序存在对定义在一个库中的全局变量的引用,由于程序的数据地址必须在   链接时被绑定,因此链接器不得不在程序中创建一个该变量的副本,如图4所示。

    1K40

    含大量图文解析及例程 | Linux下的ELF文件、链接、加载与库(下)

    入口函数和运行库 入口函数 初学者可能一直以来都认为C程序的第一条指令就是从我们的main函数开始的,实际上并不是这样,在main开始前和结束后,系统其实帮我们做了很多准备工作和扫尾工作,下面这个例子可以证明...事实上操作系统装载程序之后首先运行的代码并不是我们编写的main函数的第一行,而是某些运行库的代码,它们负责初始化main函数正常执行所需要的环境,并负责调用main函数,并且在main返回之后,记录main...在可执行文件的所有符号中,main函数是一个很特别的函数,对C/C++程序开发人员来说,main函数是整个程序的起点;但是,main函数却不是程序启动后真正首先执行的代码。...当 ld 将外部符号的地址都确定好之后,才将指令指针执行程序本身的_start。也就是说,在动态链接的可执行文件中,第一条指令应该在链接加载器 ld 中。...共享库和静态库的区别:在链接libc共享库时只是指定了动态链接器和该程序所需要的库文件,并没有真的做链接,可执行文件调用的libc库函数仍然是未定义符号,要在运行时做动态链接。

    1.5K23

    GCC 编译器的使用

    在日常交流中通常使用“编译”统称这 4 个步骤,如果不是特指这 4 个步骤中的某一个,本教程也依惯例使用“编译”这个统称。...在日常交流中通常使用“编译”统称这 4 个步骤,如果不是特指这 4 个步骤中的某一个,本教程也依惯例使用“编译”这个统称。...现在试试其他选项,以下命令生成的 main.s 是 main.c 的汇编语言文件: $ gcc -S -o main.s main.c 以下命令对 main.c 进行预处理,并将得到的结果打印出来。...命令如下: $ gcc -E main.c 2.4 警告选项(Warning Option) (1)-Wall 这个选项基本打开了所有需要注意的警告信息,比如没有指定类型的声明、在声明之前就使用的函数...不使用-O'或-O1’选项的目的是减少编译的开销,使编译结果能够调试、语句是独立的:如果在两条语句之间用断点中止程序,可以对任何变量重新赋值,或者在函数体内把程序计数器指到其他语句,以及从源程序中精确地获取你所期待的结果

    3.9K31

    并发问题解密:探索多线程和锁机制

    .描述:pthread_create()函数在调用进程中启动一个新线程。...(4)进程中的任何线程都调用exit(),或者主线程执行main()的返回。这将导致进程中所有线程的终止。...thread在返回之前,成功调用pthread_create()将新线程的ID存储在thread指向的缓冲区中;此标识符用于在后续调用其他pthreads函数时引用线程。...start_routine线程入口函数arg线程入口函数的参数返回值:成功时,返回0;出错时,它返回一个错误号,并且*thread的内容未定义。...互斥锁的属性在创建锁的时候指定,在实现中仅有一个锁类型属性,不同的锁类型在试图对一个已经被锁定的互斥锁加锁时表现不同。返回:成功会返回零,其他任何返回值都表示出现了错误。

    22310

    程序一定要从main函数开始运行吗?

    ,在链接器扫描完所有的输入目标文件后,所有这种未定义的符号都应该能在全局符号表中找到,否则报符号未定义错误。...编译器的编译选项是: -ffunction-sections -fdata-sections 可能很多人都会以为程序都是由main函数开始执行和结束的,但其实不是,在main函数调用之前,为了保证程序可以顺利进行...Linux一般程序的入口是__start函数,程序有两个相关的段: init段:进程的初始化代码,一个程序开始运行时,在main函数调用之前,会先运行.init段中的代码。...A:该符号的值是绝对的,在以后的链接过程中,不允许进行改变。这样的符号值,常常出现在中断向量表中,例如用符号来表示各个中断向量函数在中断向量表中的位置。...I:该符号对另一个符号的间接引用 N:debug符号 R:该符号位于只读数据区 T:该符号位于代码段 U:该符号在当前文件未定义,定义在别的文件中 ?

    1.3K30

    ubuntu gcc编译时对’xxxx’未定义的引用问题

    http://www.cnblogs.com/oloroso/p/4688426.html gcc编译时对’xxxx’未定义的引用问题 原因 解决办法 gcc 依赖顺序问题 在使用gcc编译的时候有时候会碰到这样的问题...dso.o:在函数‘dso_load(char const*, char const*)’中: dso.cpp:(.text+0x3c):对‘dlopen’未定义的引用 dso.cpp:(.text+0x4c...):对‘dlsym’未定义的引用 dso.cpp:(.text+0xb5):对‘dlerror’未定义的引用 dso.cpp:(.text+0x13e):对‘dlclose’未定义的引用 原因 出现这种情况的原因...但是在链接为可执行文件的时候就必须要具体的实现了。如果错误是未声明的引用,那就是找不到函数的原型,解决办法这里就不细致说了,通常是相关的头文件未包含。...例如:在main.c中使用了pthread库相关函数,那么编译的时候必须是main.c在前,-lpthread在后。gcc main.c -lpthread -o a.out。

    8.2K20

    应用程序的加载——dyld动态链接器的工作流程

    现在我们知道了,动态库是在程序启动的时候被加载到内存中的,那么它是怎么被加载到内存中的呢?答案就是通过系统的动态链接器dyld: ?...在iOS/Mac操作系统当中,只有很少量的进程只需要内核就能完成加载,基本上所有的进程都是动态链接的,所以Mach-O镜像文件中会有很多对外部的库和符号的引用,但是这些引用并不能直接使用,在启动的时候还必须要通过这些引用进行内容的填补...、arm)对_dyld_start分别做了不同的实现处理 。...这个函数也就是我们 app 开始的地方 dyldbootstrap :: start 首先,我们在源码中搜索dyldbootstrap::start,结果如下: ?...还是借用 LLDB 调试堆栈结果,我们在上面源码的最后一行,找到了 dyldbootstrap::start 函数之后走的是 dyld::_main 函数: return dyld::_main((macho_header

    2K10

    main函数真的是C程序的开始吗?

    我们在学习和编写C程序时,都是从main函数开始,main函数作为入口函数已经深深地印在我们的脑海中,那么main函数真的是C程序的入口函数吗?带着这个问题我们先来看下面一段代码。 1....怎么和我们刚开始学习C程序时说的不一样呢?从运行结果中,我们可以看出来beforeMain是在进入main函数之前被调用的,这对于C语言的初学者来说似乎有点难以理解。...构造函数属性使函数在执行进入main()之前自动被调用 GNU C的一大特色就是__attribute__机制。...同理, destructor让系统在main()函数退出或者调用了exit()之后,调用我们的函数。...在main函数之前,执行一个函数,便于我们做一些准备工作;在main()函数退出或者调用了exit()之后调用。

    53610

    【故障分析+解决】解决链接程序时,由于链接crt*.o的顺序问题导致的bug

    对有故障的程序使用objdump -D命令进行反编译,发现其_init段变成了两个: 按照之前的开发经验可以知道,_init段是存在于crt*.o这几个文件内的,链接器会把这几个文件的_init段,按照顺序拼接起来...把B编译出来的文件在A上链接,发现结果正常。 因此排除编译结果的问题,接下来把问题聚焦在链接过程上。 怀疑是机器B的系统自带的链接器有问题,因此我将A的链接器拷贝到B上,然后进行链接。发现问题依旧。...由于链接的时候使用了find命令查找crt*.o文件,并存储到一个数组中。...因此把最终调用链接器的命令打出来,发现B机器上,输入链接器的文件参数顺序如下: main.o crt1.o crtn.o crti.o crt0.o libc.a 而正常的A机器上,输入链接器的文件参数顺序如下...: main.o crt0.o crt1.o crti.o crtn.o libc.a 观察发现,机器A上,输入的crt*.o文件的顺序是按照升序排列的,而有问题的B机器则不是按照升序的。

    33220

    编译make的出错提示解决方案

    编译出错笔记: start.s:20: Error: no such instruction: `ldr r0,=WTCON' 错误:没有这样的指令 解决:编译文件后缀名必须为大写S,改为start.S...r0,#0 start.o(.text+0xc8): In function `SDRAM_CONFIG': : undefined reference to `lr' 错误:在start.S中对LR...未定义的引用 解决:在start.S中找到 ldr pc,=lr ,编译器误解lr是一个变量,这里应该写成mov pc,lr(完成一个子程序返回) 12: error: syntax error...include”标号之前有语法错误 74: warning: return type of 'main' is not `int' 错误:main函数的返回值不是int型 解决:将void main(...uart0_init函数只是隐形声明(implicit declaration),在这个文件中没有extern声明或者调用头文件 解决:1.在本文开头上添加: extern void uart0

    1.7K100
    领券