尝试在 C 中实现封装时出现链接器错误
Linker error when trying to implement encapsulation in C
考虑这些文件:
obj.h
#pragma once
struct obj;
int obj_size(void);
void obj_set_id(struct obj*, int);
int get_obj_id(struct obj*);
obj.c
#include "obj.h"
struct obj
{
int id;
};
int obj_size(void) {
return sizeof(struct obj);
}
void obj_setid(struct obj* o, int i) {
o->id = i;
}
int obj_getid(struct obj* o) {
return o->id;
}
main.c
#include <stdio.h>
#include "obj.c"
int main()
{
puts("hello world");
}
事实证明,这是在C中实现封装的方式(https://en.wikipedia.org/wiki/Opaque_pointer#C)。但是,当我尝试编译时出现链接器错误。这些是 Visual Studio 的投诉:
Error LNK2005 _obj_getid already defined in obj.obj
Error LNK2005 _obj_setid already defined in obj.obj
Error LNK2005 _obj_size already defined in obj.obj
Error LNK1169 one or more multiply defined symbols found
如果有人想知道,它已设置为编译为 C 代码。
这些是我尝试用 clang 编译它时遇到的错误:
clang-7 -pthread -lm -o main main.c obj.c
/tmp/obj-36b460.o: In function `obj_getid':
obj.c:(.text+0x30): multiple definition of `obj_getid'
/tmp/main-a2c3dc.o:main.c:(.text+0x30): first defined here
/tmp/obj-36b460.o: In function `obj_setid':
obj.c:(.text+0x10): multiple definition of `obj_setid'
/tmp/main-a2c3dc.o:main.c:(.text+0x10): first defined here
/tmp/obj-36b460.o: In function `obj_size':
obj.c:(.text+0x0): multiple definition of `obj_size'
/tmp/main-a2c3dc.o:main.c:(.text+0x0): first defined here
/tmp/main-a2c3dc.o: In function `main':
main.c:(.text+0x59): undefined reference to `obj_set_id'
clang-7: error: linker command failed with exit code 1 (use -v to see invocation)
compiler exit status 1
我已经尝试 extern
-ing obj.h
中的函数声明,但这也没有用。 inline
-ing 他们也一样。
以当前状态回答您的问题:
您的错误是包含 "obj.c" 而不是 "obj.h"。
#include
指令有效(简而言之),例如命名文件的内容替换了指令。
如果您编译 "main.c" 和 "obj.c",您会将 "obj.c" 中的所有内容两次提供给链接器。这就是它给你错误的原因。
如果您有新信息,可以编辑您的问题进行更新。
考虑这些文件:
obj.h
#pragma once
struct obj;
int obj_size(void);
void obj_set_id(struct obj*, int);
int get_obj_id(struct obj*);
obj.c
#include "obj.h"
struct obj
{
int id;
};
int obj_size(void) {
return sizeof(struct obj);
}
void obj_setid(struct obj* o, int i) {
o->id = i;
}
int obj_getid(struct obj* o) {
return o->id;
}
main.c
#include <stdio.h>
#include "obj.c"
int main()
{
puts("hello world");
}
事实证明,这是在C中实现封装的方式(https://en.wikipedia.org/wiki/Opaque_pointer#C)。但是,当我尝试编译时出现链接器错误。这些是 Visual Studio 的投诉:
Error LNK2005 _obj_getid already defined in obj.obj
Error LNK2005 _obj_setid already defined in obj.obj
Error LNK2005 _obj_size already defined in obj.obj
Error LNK1169 one or more multiply defined symbols found
如果有人想知道,它已设置为编译为 C 代码。
这些是我尝试用 clang 编译它时遇到的错误:
clang-7 -pthread -lm -o main main.c obj.c
/tmp/obj-36b460.o: In function `obj_getid':
obj.c:(.text+0x30): multiple definition of `obj_getid'
/tmp/main-a2c3dc.o:main.c:(.text+0x30): first defined here
/tmp/obj-36b460.o: In function `obj_setid':
obj.c:(.text+0x10): multiple definition of `obj_setid'
/tmp/main-a2c3dc.o:main.c:(.text+0x10): first defined here
/tmp/obj-36b460.o: In function `obj_size':
obj.c:(.text+0x0): multiple definition of `obj_size'
/tmp/main-a2c3dc.o:main.c:(.text+0x0): first defined here
/tmp/main-a2c3dc.o: In function `main':
main.c:(.text+0x59): undefined reference to `obj_set_id'
clang-7: error: linker command failed with exit code 1 (use -v to see invocation)
compiler exit status 1
我已经尝试 extern
-ing obj.h
中的函数声明,但这也没有用。 inline
-ing 他们也一样。
以当前状态回答您的问题:
您的错误是包含 "obj.c" 而不是 "obj.h"。
#include
指令有效(简而言之),例如命名文件的内容替换了指令。
如果您编译 "main.c" 和 "obj.c",您会将 "obj.c" 中的所有内容两次提供给链接器。这就是它给你错误的原因。
如果您有新信息,可以编辑您的问题进行更新。