一、C語言中調(diào)用C++函數(shù)
將 C++ 函數(shù)聲明為``extern "C"''(在你的 C++ 代碼里做這個(gè)聲明),然后調(diào)用它(在你的 C 或者 C++ 代碼里調(diào)用)。例如:
// C++ code:
extern "C" void f(int);
void f(int i)
{
// ...
}
然后,你可以這樣使用 f():
void f(int);
void cc(int i)
{
f(i);
}
當(dāng)然,這招只適用于非成員函數(shù)。如果你想要在 C 里調(diào)用成員函數(shù)(包括虛函數(shù)),則需要提供一個(gè)簡單的包裝(wrapper)。例如:
// C++ code:
class C
{
// ...
virtual double f(int);
};
extern "C" double call_C_f(C* p, int i) // wrapper function
{
return p->f(i);
}
然后,你就可以這樣調(diào)用 C::f():
double call_C_f(struct C* p, int i);
void ccc(struct C* p, int i)
{
double d = call_C_f(p,i);
}
如果你想在 C 里調(diào)用重載函數(shù),則必須提供不同名字的包裝,這樣才能被 C 代碼調(diào)用。例如:
// C++ code:
void f(int);
void f(double);
extern "C" void f_i(int i) { f(i); }
extern "C" void f_d(double d) { f(d); }
然后,你可以這樣使用每個(gè)重載的 f():
void f_i(int);
void f_d(double);
void cccc(int i,double d)
{
f_i(i);
f_d(d);
}
注意,這些技巧也適用于在 C 里調(diào)用 C++ 類庫,即使你不能(或者不想)修改 C++ 頭文件。
二、C++中調(diào)用C函數(shù)
要讓你的C代碼既能被C代碼又能被C++調(diào)用雖說容易,但是還是有需要注意的地方。
現(xiàn)有三個(gè)文件分別如下:
#ifndef TESTC_H
#define TESTC_H
#ifdef __cplusplus
extern "C" {
#endif
int add(int a, int b);
#ifdef __cplusplus
}
#endif
#endif
#include "TestC.h"
int add(int a, int b)
{
return (a + b);
}
#include "stdio.h"
#include "TestC.h"
int main()
{
printf("add = %d\n", add(2, 5));
return 0;
}
說明:
file TestC.h是C的頭文件,file TestC.c是其實(shí)現(xiàn)文件,file TestCpp.cpp是調(diào)用C函數(shù)的C++文件。
文件TestC.h中的TESTC_H定義是為了頭文件保護(hù),” #ifdef __cplusplus”這個(gè)不能缺少,你可以去查看C的標(biāo)準(zhǔn)庫頭文件中都有這個(gè),如”stdio.h”。有了這個(gè)宏編譯器就知道現(xiàn)在是C還是C++在調(diào)用它。
為什么要區(qū)分C與C++調(diào)用呢?其深層次原因是因?yàn)镃和C++編譯器在編譯和鏈接時(shí)對于函數(shù)的處理不一樣。C++為了支持函數(shù)重載在編譯時(shí)會加入函數(shù)參數(shù)及類型信息。如上面的add方法,C編譯器編譯后在符號庫中的名字為_add,而C++編譯器則會產(chǎn)生像_add_int_int之類的名字。C++正是依靠這種機(jī)制實(shí)現(xiàn)了函數(shù)的重載。
extern關(guān)鍵字表示將函數(shù)或變量聲明為全局類型,與之相對應(yīng)的是static。static限定函數(shù)或變量的作用域?yàn)楸疚募xtern還有一個(gè)作用就是與”C”連在一起使用,即extern “C”通知編譯器將extern “C”所包含的代碼按照C的方式編譯和鏈接