编译具有相同标头的 C 和 C++ 文件时未定义的引用

Posted

技术标签:

【中文标题】编译具有相同标头的 C 和 C++ 文件时未定义的引用【英文标题】:Undefined reference when compiling a C and C++ file with same header 【发布时间】:2019-12-11 13:03:39 【问题描述】:

为了简短起见,我有一个 CPP 和 C 代码,而我的 CPP 代码试图从带有头文件的 C 代码中引用函数。每当我运行 make 命令时,我最终都会收到“未定义的引用”错误。这是我的代码:

cpp_code.cpp:

extern "C"
    #include "header_code.h";


int main()
    cout << "Hello" << endl;
    return 0;

c_code.c:

#include "header_code.h"

int main()
    printf("Hello");
    return 0;


void initalize()
    printf("Initilized");

header_code.h:

extern void initalize();

制作文件:

CXX = g++
CXXFLAGS = -std=c++11
CC = gcc
DEPS = header_code.h
CFLAGS = -I
OBJS = cpp_code.o c_code.o

c: $(OBJS) 
    $(CXX) -o $@ $^ $(CXXFLAGS)

%.o : %.cpp
    $(CXX) -c $(CXXFLAGS) $<

%.o : %.c $(DEPS)
    $(CC) -c $(CFLAGS) $<

每当运行 make 它总是给我带来问题。谁能帮帮我吗?感谢您花时间阅读所有这些内容!

【问题讨论】:

这能回答你的问题吗? What is an undefined reference/unresolved external symbol error and how do I fix it? 两个main函数? 尝试指定您在以后的问题中遇到的确切错误。 在发布之前确保您的示例代码中没有出现完全不相关的错误。示例:CFLAGS = -I 将使 $&lt; 被视为包含目录而不是源文件。 【参考方案1】:

[basic.start.main]

在全局范围内声明变量 main 的程序,或在附加到命名模块的全局范围内声明函数 main,或通过 C 语言链接声明名称 main 的程序(在任何命名空间中)格式不正确。

因此,作为C++ 程序,它的格式不正确。删除 C main 函数。

其他问题:

在你的makefile中CFLAGS = -I 并且在编译之后发生的任何事情都将被视为在其中搜索头文件的目录。在您的makefile中,这就是源文件。更正:CFLAGS =CFLAGS = -I.

您的头文件缺少标头保护,并且应该由 C 和 C++ 代码使用的头文件通常包含 extern "C" 部分,以免 C++ 用户添加它。

cpp_code.cpp

#include "header_code.h"
#include <iostream>

int main() 
    initalize(); // call the C function
    std::cout << "Hello" << std::endl;

c_code.c

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

void initalize()
    printf("Initilized");

header_code.h

#ifndef HEADER_CODE_H_
#define HEADER_CODE_H_

#ifdef __cplusplus
extern "C" 
#endif

extern void initalize();

#ifdef __cplusplus

#endif

#endif

制作文件

CXX = g++
CXXFLAGS = -std=c++11
CC = gcc
DEPS = header_code.h
CFLAGS = -I.
OBJS = cpp_code.o c_code.o

c: $(OBJS) 
    $(CXX) -o $@ $^ $(CXXFLAGS)

%.o : %.cpp
    $(CXX) -c $(CXXFLAGS) $<

%.o : %.c $(DEPS)
    $(CC) -c $(CFLAGS) $<

【讨论】:

除非我拼错了某些东西,我认为我不是,否则我仍然会收到未定义的“初始化”错误引用。不过,我确实要感谢您对您的回答如此透彻,非常感谢! @AugustoCelis 如果您只是从我的答案中复制文件(并确保 makefile 在应有的位置获得 字符),您将不会获得任何未定义的引用。您拼错了“initialize”,但我让它这样,并且在所有 3 个文件中都拼写为“initialize” - 所以,没有未定义的引用。 它确实有效。很抱歉这么晚才回复,但非常感谢!

以上是关于编译具有相同标头的 C 和 C++ 文件时未定义的引用的主要内容,如果未能解决你的问题,请参考以下文章

为 C++ 编译时未找到符号,但为 C 找到了符号

仅具有标头实现的重复符号[重复]

链接到 MacOS 上预编译的 QuantLib 二进制文件时未定义的 Boost 符号

带有条件编译的 c++ 标头包含顺序

使用用于 C++ 代码的标头编译 C 代码时未知类型名称 char16_t

为 f2py 使用 C++ 源时未定义的符号