【问题标题】:How to statically link a library which links dynamically another library?如何静态链接一个动态链接另一个库的库?
【发布时间】:2016-04-09 17:58:08
【问题描述】:

我在使用GCC时遇到以下情况:

我有一个名为 A.DLL动态 库,它可以正确编译和链接并生成 LIBA.A

现在,我有另一个名为 LIBB.A静态 库,它有一个使用来自 A.DLLafunc() 的函数定义。这也可以正确编译和链接并生成 LIBB.A

但是,当我在另一个程序 PROGC.C 中使用 LIBB.A 来编译为可执行程序 PROGC.EXE 时,GCC 无法使用 LIBA.A 链接到 A.DLL

它给出了错误:undefined reference to afunc()

我尝试了以下操作:

 gcc PROGC.C -o PROGC.EXE -lLIBB.A -Wl,-Bdynamic -lLIBA.A ...

但无法成功链接。

我的问题是这是否可能?如果是,该怎么做?如果不是,为什么不是?

(提前致谢。)

【问题讨论】:

  • 也许你没有使用相同的调用约定!!!
  • 你是如何构建你的 libb.a 的?
  • @jdarthenay 我正在使用以下内容来构建 libb.a:gcc.exe ... -c B.c -o B.oar.exe -r -s LIBB.A B.o 。但是,正如@milevyo 所问,我没有在任何库中使用任何显式调用约定。这是一个问题吗?附:我正在使用相同的编译器构建所有内容。
  • 您是否成功地将程序仅链接到 a.dll? (没有 libb)。
  • 是的!在我的例子中,另一个类似的例子是 A.dll 是预编译的 opengl32.dlllibb.a 是一个静态库,它有一个使用 opengl draw functions 的单个函数定义,并且仅当我使用 libb.a 中的特定函数时,我才遇到相同的链接错误。但我总是能够动态链接 opengl32.

标签: c gcc linker static-linking dynamic-linking


【解决方案1】:

这是一个你尝试做的例子:

啊哈:

#ifndef A_H
#define A_H

#ifdef BUILD_A_DLL
#define EXPORT __declspec(dllexport)
#else
#define EXPORT __declspec(dllimport)
#endif

#ifdef __cplusplus
extern "C"
{
#endif

extern EXPORT void __cdecl print_a_version();

#ifdef __cplusplus
}
#endif

#endif

交流:

#define BUILD_A_DLL

#include "a.h"

#include <stdio.h>

EXPORT void __cdecl print_a_version()
{
    printf("A: v1.0\n");
}

b.h:

#ifndef B_H
#define B_H

extern void print_b_version();

#endif

b.c:

#include "b.h"

#include <stdio.h>

#include "a.h"

void print_b_version()
{
    print_a_version();
    printf("B: v1.0\n");
}

stackoverflow.c:

#include "b.h"

int main()
{
    print_b_version();

    return 0;
}

makefile(用于 mingw-64):

CC=GCC
AR=ar
WINVER=0x0400
CFLAGS=-Wformat -std=gnu99 -Wall -Werror -DWINVER=$(WINVER) -std=gnu99
LDFLAGSDLL=-shared -Wl,--out-implib,liba.a
LDFLAGS=-L. -lb -la

all:a.dll libb.a stackoverflow.exe

a.dll:a.o
    $(CC) $(CFLAGS) -o a.dll a.o $(LDFLAGSDLL)

a.o:a.c a.h
    $(CC) $(CFLAGS) -c a.c

libb.a:b.o
    $(AR) -rs libb.a b.o

b.o:b.c b.h a.h
    $(CC) $(CFLAGS) -c b.c

stackoverflow.exe:stackoverflow.o libb.a
    $(CC) $(CFLAGS) -o stackoverflow.exe stackoverflow.o $(LDFLAGS)

stackoverflow.o:stackoverflow.c b.h
    $(CC) $(CFLAGS) -c stackoverflow.c

mrproper:clean
    for %%i in (a.dll liba.dll libb.o stackoverflow.exe) do if exist %%i del %%i

clean:
    for %%i in (a.o b.o stackoverflow.o) do if exist %%i del %%i

.PHONY:all clean mrproper

这对我有用。

编辑:重要提示 - -l 标志的顺序非常重要。使用LDFLAGS=-L. -la -lb 构建“stackoverflow.exe”失败。

【讨论】:

  • 我发现我的错误在于链接顺序,因为还有其他库。
猜你喜欢
  • 2023-04-04
  • 2012-07-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多