在cygwin中与gcc动态链接时未定义的引用

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)

Qua*_*nic 6

我在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)

但是我仍然想知道为什么我不需要为我的简单测试做这个.