C与Cpp混合调用

本文探讨了在C与C++混合编程中如何处理函数重载问题。C语言不支持函数重载,而C++通过方法签名的mangled name实现。通过extern "C"可以解决两者间的调用问题。文章提供了一个C调用C++和C++调用C的示例,并解释了"external"关键字的作用。在实践中,需要注意C++代码中避免使用C无法访问的库,以及在C++中对C头文件的适当包装。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

函数重载

  • C 语言不支持重载,相同名字会报错
  • C++支持重载,通过compile的中间流程,生成含有方法签名信息(形参类型、形参顺序、方法名称)新的方法名称(mangled name),来进行重载
  • 通过 extern “C” 可以解决混编问题
重载定义
  • 同一作用域类
  • 函数名相同
  • 参数列表不同(个数不同或类型不同)
  • 返回值任意

代码

git地址:git@github.com:AlbertSnow/algorithm.git

C 调用 CPP
  1. CPP在cpp文件中添加
// #include <iostream>
#include <stdio.h>
extern "C" {
void CallCpp()
{
    printf("++++++ Im cpp +++++++");
    // std::cout << "I'm out this place";
}
}
  1. 注意不能有C无法访问的库
  2. 头文件不用加 extern
CPP 调用 C
  1. extern 来wrap 头文件
#include <iostream>

extern "C" {
#include "CLang.h"
}

int main() {
    std::cout << "----- Cpp call c method -----\n";
    CallC();
}

总结

  1. C不支持函数名称重载,C++支持
  2. external关键字
    • c 调用 cpp, 在CPP的cpp文件中wrap实现
    • cpp 调用 c, 在CPP的cpp文件中wrap 对c头文件的include
external
  1. external functionName
    表示 symbol 来自于外界,先通过编译,之后再链接

CppCallC 报错

Undefined symbols for architecture x86_64:
  "CallC()", referenced from:
      _main in CppCallC-54e9db.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [install] Error 1

C Call cpp,but contain none c library method

gcc -o C_call_Cpp_Program CCallCpp.c CppLang.o
Undefined symbols for architecture x86_64:
  "std::__1::locale::use_facet(std::__1::locale::id&) const", referenced from:
      std::__1::ctype<char> const& std::__1::use_facet<std::__1::ctype<char> >(std::__1::locale const&) in CppLang.o
  "std::__1::ios_base::getloc() const", referenced from:
      std::__1::basic_ios<char, std::__1::char_traits<char> >::widen(char) const in CppLang.o
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::__init(unsigned long, char)", referenced from:
      std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::basic_string(unsigned long, char) in CppLang.o
  "std::__1::basic_string<char, std::__1::char_traits<char>, std::__1::allocator<char> >::~basic_string()", referenced from:
      std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> > std::__1::__pad_and_output<char, std::__1::char_traits<char> >(std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> >, char const*, char const*, char const*, std::__1::ios_base&, char) in CppLang.o
  "std::__1::basic_ostream<char, std::__1::char_traits<char> >::sentry::sentry(std::__1::basic_ostream<char, std::__1::char_traits<char> >&)", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in CppLang.o
  "std::__1::basic_ostream<char, std::__1::char_traits<char> >::sentry::~sentry()", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in CppLang.o
  "std::__1::cout", referenced from:
      _CallCpp in CppLang.o
  "std::__1::ctype<char>::id", referenced from:
      std::__1::ctype<char> const& std::__1::use_facet<std::__1::ctype<char> >(std::__1::locale const&) in CppLang.o
  "std::__1::locale::~locale()", referenced from:
      std::__1::basic_ios<char, std::__1::char_traits<char> >::widen(char) const in CppLang.o
  "std::__1::ios_base::__set_badbit_and_consider_rethrow()", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in CppLang.o
  "std::__1::ios_base::clear(unsigned int)", referenced from:
      std::__1::ios_base::setstate(unsigned int) in CppLang.o
  "std::terminate()", referenced from:
      ___clang_call_terminate in CppLang.o
  "___cxa_begin_catch", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in CppLang.o
      ___clang_call_terminate in CppLang.o
  "___cxa_call_unexpected", referenced from:
      std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> >::ostreambuf_iterator(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) in CppLang.o
  "___cxa_end_catch", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in CppLang.o
  "___gxx_personality_v0", referenced from:
      std::__1::basic_ostream<char, std::__1::char_traits<char> >& std::__1::__put_character_sequence<char, std::__1::char_traits<char> >(std::__1::basic_ostream<char, std::__1::char_traits<char> >&, char const*, unsigned long) in CppLang.o
      std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> > std::__1::__pad_and_output<char, std::__1::char_traits<char> >(std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> >, char const*, char const*, char const*, std::__1::ios_base&, char) in CppLang.o
      std::__1::ostreambuf_iterator<char, std::__1::char_traits<char> >::ostreambuf_iterator(std::__1::basic_ostream<char, std::__1::char_traits<char> >&) in CppLang.o
      std::__1::basic_ios<char, std::__1::char_traits<char> >::widen(char) const in CppLang.o
      Dwarf Exception Unwind Info (__eh_frame) in CppLang.o
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
make: *** [install] Error 1
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值