龙盟编程博客 | 无障碍搜索 | 云盘搜索神器
快速搜索
主页 > 软件开发 > C/C++开发 >

C++语言常见问题解答(4)

时间:2009-12-22 15:42来源:未知 作者:admin 点击:
分享到:
== Part 4/4 ============================ ======================================= ■□ 第17节:和 C 连结/和 C 的关系 ================================

   == Part 4/4  ============================ 

  

======================================= 

  

■□ 第17节:和 C 连结/和 C 的关系 

  

======================================= 

  

 

  

Q105:怎样从 C++ 中呼叫 C 的函数 "f(int,char,float)"? 

  

 

  

告诉 C++ 编译器说:它是个 C 的函数: 

  

   extern "C" void f(int,char,float); 

  

 

  

确定你有 include 进来完整的函数原型 (function prototype)。一堆 C 的函数可 

  

以用大括号框起来,如下: 

  

 

  

   extern "C" { 

  

   void* malloc(size_t); 

  

   char* strcpy(char* dest, const char* src); 

  

   int   printf(const char* fmt, ...); 

  

   } 

  

 

  

======================================== 

  

 

  

Q106:怎样才能建一个 C++ 函数 "f(int,char,float)",又能被 C 呼叫? 

  

 

  

想让 C++ 编译器知道 "f(int,char,float)" 会被 C 编译器用到的话,就要用到前 

  

一则 FAQ 已详述的 "extern C" 语法。接著在 C++ 模组内定义该函数: 

  

 

  

   void f(int x, char y, float z) 

  

   { 

  

   //... 

  

   } 

  

 

  

"extern C" 一行会告诉编译器:送到 linker 的外部资讯要采用 C 的呼叫惯例及签 

  

名编码法(譬如,前置一个底线)。既然 C 没有多载名称的能力,你就不能让 C 程 

  

式能同时呼叫得到多载的函数群。 

  

 

  

警告以及实作相关事项: 

  

  * 你的 "main()" 应该用 C++ 编译之(为了静态物件的初始化)。 

  

  * 你的 C++ 编译器应该能设定连结的程序(为某些非凡的程式库)。 

  

  * 你的 C 和 C++ 编译器可能要是同一个牌子的,而且是相容的版本(亦即:有相 

  

    同的呼叫惯例等等)。 

  

 

  

======================================== 

  

 

  

Q107:为什麽 linker 有这种错误讯息:C/C++ 函数被 C/C++ 函数呼叫到? 

  

 

  

看前两则 FAQs 关於 extern "C" 的使用。 

  

 

  

======================================== 

  

 

  

Q108:该怎麽把 C++ 类别的物件传给/传自 C 的函数? 

  

 

  

例子: 

  

 

  

  

   /****** C/C++ header file: Fred.h ******/ 

  

   #ifdef __cplusplus  /*"__cplusplus" is #defined if/only-if 

  

      compiler is C++*/ 

  

   extern "C" { 

  

   #endif 

  

 

  

   #ifdef __STDC__ 

  

   extern void c_fn(strUCt Fred*);   /* ANSI-C prototypes */ 

  

   extern struct Fred* cplusplus_callback_fn(struct Fred*); 

  

   #else 

  

   extern void c_fn();     /* K&R style */ 

  

   extern struct Fred* cplusplus_callback_fn(); 

  

   #endif 

  

 

  

   #ifdef __cplusplus 

  

   } 

  

   #endif 

  

 

  

   #ifdef __cplusplus 

  

   class Fred { 

  

   public: 

  

   Fred(); 

  

   void wilma(int); 

  

   private: 

  

   int a_; 

  

   }; 

  

   #endif 

  

 

  

"Fred.C" 是个 C++ 模组: 

  

 

  

   #include "Fred.h" 

  

   Fred::Fred() : a_(0) { } 

  

   void Fred::wilma(int a) : a_(a) { } 

  

 

  

   Fred* cplusplus_callback_fn(Fred* fred) 

  

   { 

  

   fred->wilma(123); 

  

   return fred; 

  

   } 

  

 

  

"main.C" 是个 C++ 模组: 

  

 

  

   #include "Fred.h" 

  

 

  

   int main() 

  

   { 

  

   Fred fred; 

  

   c_fn(&fred); 

  

   return 0; 

  

   } 

  

 

  

"c-fn.c" 是个 C 模组: 

  

 

  

   #include "Fred.h" 

  

  

   void c_fn(struct Fred* fred) 

  

   { 

  

   cplusplus_callback_fn(fred); 

  

   } 

  

 

  

把指向 C++ 物件的指标传到/传自 C 的函数,假如传出与收回的指标不是“完全相 

  

同”的话,就会失败。譬如,不要传出一个基底类别的指标却收回一个衍生类别的指 

  

标,因为 C 编译器不懂该怎麽对多重及虚拟继续的指标做转型。 

  

 

  

======================================== 

  

 

  

Q109:C 的函数能不能存取 C++ 类别的物件资料? 

  

 

  

有时可以。 

  

 

  

(请先读一读前一则关於和 C 函数间传递 C++ 物件的 FAQ。)

  

精彩图集

赞助商链接