1. 头文件 test.h 的写法
因为头文件可能被c或c++使用,所以要加上#ifdef __cplusplus的判断。
C编译器是不认识 extern "C" 。
cpp
#ifdef MYLIB_EXPORTS
#define MYLIB_API __declspec(dllexport)
#else
#define MYLIB_API __declspec(dllimport)
#endif
#ifdef __cplusplus
extern "C"{
#endif
// 函数:不需要 extern,加上也可以(多余)
//在 C 和 C++ 中,函数声明默认就是 extern 的(即具有外部链接性,可以被其他编译单元访问)。
MYLIB_API void test_func(int a, int b);
//全局变量:extern 必须
//写法 1:extern 在最前面
extern MYLIB_API int g_counter;
extern MYLIB_API char g_name[64];
//写法 2:extern 在 MYLIB_API 后面(同样正确)
//MYLIB_API extern int g_counter;
//MYLIB_API extern char g_name[64];
//...
#ifdef__cplusplus
}
#endif
2. 实现文件的写法
-
2.1 实现文件是.c文件
因为.c文件时用c编译器编译的,所以自然会以C的方式导出函数
-
2.2 实现文件是.cpp文件
因为是用c++编译器编译,c++默认会改写函数名,若要让它用C的方式导出,必须显示告知它。
cpp#include "test.h" // 这里可以没有 extern "C",因为包含了头文件,编译器会知道这些函数需要 C 链接方式。 //若头文件中按规矩写,通常cpp中不用写。比如可参看libevent库的实现 // // 若头文件没有按标准写,则需要用extern "C" 显示告诉c++编译器以C的方式导出 extern "C"{ //定义全局变量(分配内存),可不加MY_API,通常不写 int g_counter = 0; MY_API char g_name[64] = "Default Name"; //MYLIB_API可不写,通常不写 MYLIB_API void test_func(int a, int b) { //... } }