专业定制网站开发,常州seo第一人,湛江网站建设哪家优惠多,注册新公司名称查询C与C的相互调用方法 C与C为什么相互调用的方式不同C中调用CC中调用C致谢 C与C为什么相互调用的方式不同 C 和 C 之间的相互调用方式存在区别#xff0c;主要是由于 C 和 C 语言本身的设计和特性不同。
函数调用和参数传递方式不同#xff1a;C 和 C 在函数调用和参数传递方面… C与C的相互调用方法 C与C为什么相互调用的方式不同C中调用CC中调用C致谢 C与C为什么相互调用的方式不同 C 和 C 之间的相互调用方式存在区别主要是由于 C 和 C 语言本身的设计和特性不同。
函数调用和参数传递方式不同C 和 C 在函数调用和参数传递方面有一些不同之处。C 使用标准的函数调用约定而 C 在函数调用中可能包含额外的信息如函数重载和默认参数。为了正确匹配函数签名C 编译器可能会在函数名上进行名称修饰name mangling。函数重载和名称修饰C 支持函数重载即可以有相同的函数名但不同的参数列表。为了在可执行文件中区分这些重载函数C 编译器会在函数名中添加一些信息以便于重载解析。这与 C 的函数名约定不同C 中函数名是平铺的。链接库的差异C 和 C 编译器链接不同的标准库。C 编译器链接 C 标准库而 C 编译器链接 C 标准库。由于标准库可能涉及不同的函数和数据结构因此在链接阶段可能会有不同的处理。编译器特性C 和 C 编译器对代码的解析、优化、链接等可能会有不同的处理方式这可能会导致在 C 和 C 相互调用时需要进行适当的处理。 解决手段为了在 C 和 C 之间实现相互调用C 引入了 extern “C” 语法它可以用来告诉 C 编译器在函数声明上使用 C 的调用约定以便在链接阶段能够正确解析函数名。这种设计是为了在 C 和 C 之间实现互操作性但由于两者的语法和特性存在差异因此在调用方式、编译器行为和链接方式上会存在一些差异。
C中调用C 话不多说直接上案例下面是一个简单的示例演示了如何在 C 代码中调用 C 函数 首先分别创建三个文件mylib.c、mylib.h 和 main.cpp mylib.c如下
// mylib.c
#include stdio.hvoid my_c_function() {printf(This is a C function.\n);
}mylib.h如下
// mylib.h
#ifndef MYLIB_H
#define MYLIB_Hvoid my_c_function();#endif // MYLIB_Hmain.cpp如下
// main.cpp
#include iostreamextern C {// 声明 C 函数的原型void my_c_function();
}int main() {std::cout Calling a C function from C: std::endl;// 调用 C 函数my_c_function();return 0;
}在这个示例中我们使用了 #include mylib.h 来引入头文件并在 C 中调用了 my_c_function()。这样就能正确地在 C 中调用 C 函数。编译步骤如下
gcc -c mylib.c -o mylib.o # 编译 C 文件为目标文件
g -c main.cpp -o main.o # 编译 C 文件为目标文件
g main.o mylib.o -o app # 链接目标文件生成可执行文件编译后的文件列表如下 然后运行可执行文件./app得到输出结果 这里可以使用objdump命令查看编译之后的中间文件mylib.o和main.o的符号表 可以发现my_c_function()函数编译出的名称在mylib.o和main.o是相同。这是由于 C 文件中使用 extern “C” 来声明 C 调用约定以便 C 能够正确解析函数名。 我们来看看如果没有使用extern “C” 后的编译情况吧 可以发现不使用 extern “C” 函数 my_c_function 编译后名称变为了 (_Z13my_c_functionv 。 是由于在C中函数名在编译后会根据函数的参数类型和返回类型进行名称重整Name Mangling以支持函数重载等特性。这是因为C支持函数的参数类型和个数可以不同所以需要在编译后为每个函数生成一个唯一的名称。 当你在C中调用一个C函数时如果不使用 extern “C” 声明C 编译器会默认对函数名进行名称重整。而在C语言中函数名不会被重整。 如果你在C中调用了一个C函数并且没有使用 extern “C” 声明C 编译器会对函数名进行名称重整生成一个新的名字类似 _Z13my_c_functionv 这样的名称。这个过程被称为名称重整Name Mangling是为了确保函数在C中能够正确处理函数重载等特性。
C中调用C 下面还是来看一个简单的示例演示了如何在 C 代码中调用 C 函数 首先分别创建三个文件mylib.cpp、mylib.h 和 main.c mylib.cpp如下
// mylib.cpp
#include iostream#include mylib.hvoid my_cpp_function(int num) {std::cout C function called with number: num std::endl;
}mylib.h如下
// mylib.h
#ifndef MYLIB_H
#define MYLIB_H#ifdef __cplusplus
extern C {
#endifvoid my_cpp_function(int num);#ifdef __cplusplus
}
#endif#endif // MYLIB_H#endif // MYLIB_Hmain.c如下
// c_main.c
#include stdio.h#include mylib.hint main() {printf(Calling C function from C\n);// Call the C functionmy_cpp_function(42);return 0;
}在这个示例中我们使用了 #include mylib.h 来引入头文件并在 main.c 中调用了 my_cpp_function()。这样就能正确地在 C 中调用 C 函数。编译步骤如下
g -c mylib.cpp -o mylib.o # 编译 C 文件为目标文件
gcc -o main main.c mylib.o -lstdc # 链接目标文件生成可执行文件注释-lstdc 是用于链接 C 标准库的编译选项。在Linux系统中C 标准库通常被命名为 libstdc.so使用 -lstdc 编译选项可以将这个库链接到可执行文件中以便在运行时使用C的标准库函数和功能。 如果缺少 -lstdc 则会报错 编译后的文件列表如下 然后运行可执行文件./main得到输出结果 这里解释一下mylib.h头文件中的 #ifdef __cplusplus在main.c文件夹中调用mylib.h头文件但是 C 语言中并没有 extern 这个关键字因此使用 #ifdef __cplusplus来充当一个译时候的阀门。 总结一下对于C调用C的情况没有 extern “C” 这样的关键字。您需要在C代码中使用 extern “C” 来确保C函数按照C的方式进行链接同时在C代码中包含相应的头文件并调用这些函数。
致谢 本文的学习参考了以下文章C与C如何互相调用