Qua*_*nic 5 c linker gcc cygwin dynamic-linking
(这是gcc 3.3.1(长篇故事 - 责怪NIST)关于Cygwin.)
我已经编译了一些源文件gcc -c -fPIC ...来获取.o文件.
然后我做了:
$ gcc -shared -o foo.dll foo.o bar.o
Run Code Online (Sandbox Code Playgroud)
但是当我去使用它时:
$ gcc -o usefoo.exe usefoo.o -L. -lfoo
usefoo.o:usefoo.cpp:(.text+0x2e0): undefined reference to `_get_template_size'
collect2: ld returned 1 exit status
Run Code Online (Sandbox Code Playgroud)
但是,如果使用相同的.o文件,我会这样做:
$ ar rcs libfoo-static.a foo.o bar.o
Run Code Online (Sandbox Code Playgroud)
反对的链接是成功的:
$ gcc -o foo.exe foo.o -L. -lfoo-static
Run Code Online (Sandbox Code Playgroud)
对我来说奇怪的是,正如你在下面看到的那样,有问题的引用存在于.a和.dll中.那么为什么链接到.dll时出错呢?
可以在共享库中找到参考:
$ nm foo.dll|grep get_template
1001b262 T _get_template_size
Run Code Online (Sandbox Code Playgroud)
它也在静态库中:
$ nm libfoo-static.a |grep get_template
00000352 T _get_template_size
Run Code Online (Sandbox Code Playgroud)
这里是对想要使用该函数的文件中生成的符号的引用:
$ nm usefoo.o
00000000 b .bss
00000000 d .data
00000000 t .text
0000012c T __Z12ErrorMessagei
U ___main
U __alloca
U _atoi
U _get_template_size
0000026c T _main
U _printf
Run Code Online (Sandbox Code Playgroud)
更新以解决Marco的答案
有趣/令人讨厌的是,当我尝试制作一个最小的测试示例时,我无法实现它(尽管它每次都发生在真实的事情上):
func1.h:
#ifndef FUNC1_H
#define FUNC1_H
int func1(int i);
#endif
Run Code Online (Sandbox Code Playgroud)
func1.c:
#include "func1.h"
int func1(int i) {
return 2*i;
}
Run Code Online (Sandbox Code Playgroud)
usefunc.c:
#include <stdio.h>
#include "func1.h"
int main() {
printf("%d\n", func1(10));
}
Run Code Online (Sandbox Code Playgroud)
然后:
$ rm *.o *.dll *.a
$ gcc -fPIC -I. -c func1.c usefunc.c
$ gcc -shared -o func.dll func1.o
$ gcc -L. -o usefunc.exe usefunc.o -lfunc
$ ./usefunc.exe
20
Run Code Online (Sandbox Code Playgroud)
我在Cygwin网页上找到了答案(因为它解决了我的链接问题):http: //cygwin.com/cygwin-ug-net/dll.html
我最不得不做的是创建共享库并像这样做最后的链接:
$ gcc -shared -o cygfoo.dll \
-Wl,--out-implib=libfoo.dll.a \
-Wl,--export-all-symbols \
-Wl,--enable-auto-import \
-Wl,--whole-archive *.o \
-Wl,--no-whole-archive
$ gcc -L. -o usefoo.exe usefoo.o -lfoo
Run Code Online (Sandbox Code Playgroud)
但是我仍然想知道为什么我不需要为我的简单测试做这个.