例如,假设我有以下文件:hello.cpp,hello.h和main.c
在hello.cpp中说我有以下内容:
#include "hello.h"
extern "C" void test_func(int &a, int b){
some stuff
}
在hello.h中,我有以下内容:
#ifdef __cplusplus
extern "C" {
#endif
void test_func(int& a, int b);
#ifdef __cplusplus
}
#endif
这是我感到困惑的地方。如果我在main.c中具有以下内容:
#include "hello.h"
extern void test_func(int*, int);
那么这将无法正确编译。它告诉我我的hello.h文件中有错误,我认为这是因为C不支持引用传递?我注意到,如果将hello.h文件更改为“void test_func(int * a,int b)”,则此文件将正确编译。
但是,如果我的main.c文件中没有#include“hello.h”,那么它也将正确编译。而且,即使不包含hello.h,我也可以从main.c调用test_func。声明函数原型(prototype)是否足够?又为什么呢如果我想包含hello.h,这是否意味着我必须使其与C兼容并且没有任何通过引用传递的函数?
这一切都是非常新的,因此在此先感谢任何人的帮助。
最佳答案
用两个不同的原型(prototype)声明相同的C函数是未定义的行为。不要那样做。 (这种情况无论如何都可能“起作用”,因为典型的编译器通过在堆栈上放置一个内存地址来传递指针类型,并通过在堆栈上放置一个内存地址来传递引用类型。)
所以是的,您当前的hello.h根本无法从C代码使用。如果要让函数跨越C-C++“边界”,则应具有类似C的声明。 (除了可以在C++端位于命名空间中;此命名空间在C端被忽略。)
相反,您可以围绕C++函数创建一个C包装器:
// hello.h
#ifndef HELLO_H_GUARD_
#define HELLO_H_GUARD_
#ifdef __cplusplus
void test_func(int &a, int b);
extern "C"
#endif
void test_func_c(int *a, int b);
#endif
// hello.cpp
void test_func(int &a, int b) {
//...
}
extern "C"
void test_func_c(int *a, int b) {
test_func(*a, b);
}
顺便说一句,您提到了一个“main.c”文件。混合使用C和C++时,
main
函数应位于C++源文件中。如果需要,可以只是一个包装,该包装调用您的“真正的”类似于C main的函数。关于c++ - 为什么我的C程序不包含 header 就可以从C++文件调用函数?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/22211646/