链接到另一个共享对象的共享对象



我在理解以下代码如何工作时遇到了一些问题。 我有三个文件

共享.c

#include "shared.h"
void foo1 (void) {
printf("Test2");
}
void foo2 (void) {
printf ("Test1");
}

共享.h

#include <stdio.h>
extern void foo2 (void);
extern void foo1 (void);

共享2.c

//#include "shared.h"
#include "shared2.h"

void shared2 (void){
foo2();
}

共享2.h

#include <stdio.h>
#include "shared.h"
extern void shared2 (void);

测试.c

#include <stdio.h>
#include "shared2.h"

int main (void){
foo2();
}

我想创建一个二进制测试来链接 shared2.so 这取决于 shared.so 上面的代码不适用于以下命令

gcc -c -Wall -Werror -fPIC -o shared.o shared.c 
gcc -shared -o libshared.so shared.o -lc
gcc -c -Wall -Werror -fPIC -o shared2.o shared2.c
gcc -shared -o libshared2.so shared2.o -lc

由于此错误

shared2.c: In function ‘shared2’:
shared2.c:7:2: warning: implicit declaration of function ‘foo2’; did you mean ‘feof’? [-Wimplicit-function-declaration]
foo2();
^~~~
feof

但是如果我删除 Shared2.c 中的注释并在 Shared2.h 中注释同一行,上面的代码就可以工作。

  1. 为什么会出现此错误?

如果我删除错误并尝试编译 test.c

gcc -L/MyPath/ -Wall test.c -o test -lshared2 -lshared

仅当我也包含 libshared.so 时,编译才有效。

  1. 但是 libshared.so 还没有包含在 libshared2.so 中?

编辑

根据您的建议,我以这种方式更改了文件

共享.c

#include <stdio.h>
#include "shared.h"

void foo1 (void) {
printf("Test1");
}
void foo2 (void) {
printf ("Test2");
}

共享.h

extern void foo1 (void);
extern void foo2 (void);

共享2.c

#include "shared.h"
#include "shared2.h"

void shared2 (void){
foo2();
}

共享2.h

extern void shared2 (void);

并使用以下命令

gcc -c -Wall -Werror -fPIC -o shared.o shared.c 
gcc -shared -o libshared.so shared.o -lc
gcc -c -Wall -Werror -fPIC -o shared2.o shared2.c
gcc -shared -o libshared2.so shared2.o -lc

代码编译时没有错误。 相反,如果我在Shared2.cShared2.h中进行以下更改

共享2.c

#include "shared2.h"
void shared2 (void){
foo2();
}

共享2.h

#include "shared.h"
extern void shared2 (void);

我收到一个错误,我不明白为什么

shared2.c: In function ‘shared2’:
shared2.c:7:2: error: implicit declaration of function ‘foo2’; did you mean ‘feof’? [-Werror=implicit-function-declaration]
foo2();
^~~~
feof

在两种情况下,预处理器输出(替换#include "shared.h"后)是否应该相同?为什么?

继续我的测试,在编译了libshared.solibshared2.so之后,我修改了我的测试。

测试.c

#include "shared2.h"

int main (void){
shared2();
}

如果我尝试使用以下命令进行编译

gcc -L/MyPath/ -Wall -Werror test.c -o test -lshared2 

我收到一个未定义的引用错误,因为 gcc 无法找到在 Shared2.c中调用foo2()。为什么会出现此错误?如果我使用共享对象,为什么它需要引用?

您可以通过将
  1. "shared.h"包含在"shared2.c"中来消除此错误。
  2. libshared2.so 不包括您在"test"程序中使用的foo2函数的定义,这就是为什么您需要在编译时添加 libshared.so 的原因。

您的"测试"程序实际上并没有使用"libshared2.so",仅使用"libshared.so"foo2。你不需要-lshared2这里。

最新更新