【问题标题】:Linker error when trying to implement encapsulation in C尝试在 C 中实现封装时出现链接器错误
【发布时间】:2019-10-16 13:03:20
【问题描述】:

考虑这些文件:

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 的抱怨:

错误 LNK2005 _obj_getid 已在 obj.obj 中定义
错误 LNK2005 _obj_setid 已在 obj.obj 中定义
错误 LNK2005 _obj_size 已在 obj.obj 中定义
错误 LNK1169 发现一个或多个多重定义符号

如果有人想知道,它被设置为编译为 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 他们也是如此。

【问题讨论】:

  • main.c 中包含obj.h,而不是obj.c
  • 从不包含 .c 文件。
  • @500-InternalServerError 现在正在编译,但我什至无法实例化struct obj
  • 发布另一个问题。
  • @500-InternalServerError 我这样做是不是这样:void* obj = malloc(sizeof(obj_size())); obj_setid(obj, 5); printf("%d\n", obj_getid(obj)); free(obj);

标签: c linker-errors


【解决方案1】:

以当前状态回答您的问题:

您的错误是包含“obj.c”而不是“obj.h”。

#include 指令在命名文件的内容替换指令时起作用(简短地说)。

如果您编译“main.c”和“obj.c”,您会将“obj.c”中的所有内容两次提供给链接器。这就是为什么它会给你错误。


如果您有新信息,您可以编辑您的问题以更新它。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2012-01-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-04-26
    • 1970-01-01
    • 2013-06-21
    • 1970-01-01
    相关资源
    最近更新 更多