2017-10-09 187 views
1

我有一些问题需要理解下面的代码如何工作。 我有三个文件链接到另一个共享对象的共享对象

Shared.c

#include "shared.h" 

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

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

Shared.h

#include <stdio.h> 

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

Shared2.c

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


void shared2 (void){ 
    foo2(); 
} 

Shared2.h

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

extern void shared2 (void); 

test.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中吗?

编辑

您的建议我已经改变了文件,以这种方式

Shared.c

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


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

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

Shared.h

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

Shared2.c

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


void shared2 (void){ 
    foo2(); 
} 

Shared2。ħ

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.c以下更改Shared2.h

Shared2.c

#include "shared2.h" 

void shared2 (void){ 
     foo2(); 
    } 

Shared2.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编译后,我已经修改了我test.c的

test.c的

#include "shared2.h" 


int main (void){ 
    shared2(); 
} 

,如果我尝试编译与followng命令

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

我获得一个联合国因为gcc无法找到foo2(),在Shared2.c中调用。为什么这个错误?为什么它需要参考如果我使用共享对象?

+0

请注意,shared.h和shared2.h都不应包含'',因为函数声明不依赖于''中定义的任何类型。此外,“shared2.h”应该包含“shared.h”并不清楚。如果人们不能在范围中调用'shared2()'而没有'foo1()'和'foo2()'中的一个或两个,那么嵌套包含是合理的。如果人们可以在不知道或关心foo1()或foo2()的情况下调用shared2(),那么不要嵌套包含。 –

回答

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

你的“测试”程序实际上并没有使用“libshared2.so”,只有foo2来自“libshared.so”。这里你不需要-lshared2

+0

1.我做了什么:我已经将“shared.h”包含在“shared2.c”中,它可以工作。我不知道为什么它不起作用,如果我试图编译上面张贴的代码 – Bin

+0

2.你是对的,但是libshared.so是通过libshared2.so链接的:为什么我会在'测试期间写'-lshared'。 c'文件编译? – Bin

+0

1.那是因为你在“shared2.c”中使用了'foo2',但是你没有在任何地方声明它。 “共享。h“包含该声明。2.我没有正确地阅读这个问题 - 我会更新答案。 – aragaer