c接口跨平台头文件模板
程序员文章站
2022-04-27 08:16:48
...
源码模板
#ifndef XXX_H
#define XXX_H
#ifdef _WIN32
#if defined(XXX_STATIC)
#define DLL_API
#else
#if defined(DLL_EXPORTS)
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif // DLL_EXPORTS
#endif // XXX_STATIC
#define CALLSPEC __stdcall
#else
#if __GNUC__ >= 4
#define DLL_API __attribute__((visibility("default")))
#else
#define DLL_API
#endif
#define CALLSPEC
#endif // _WIN32
//--------------------data-struct------------------------------
#ifdef __cplusplus
#define ENUM(x) \
enum x
#define STRUCT(x) \
struct x
#else
#define ENUM(x) \
typedef enum x x; \
enum x
#define STRUCT(x) \
typedef struct x x; \
struct x
#endif
#ifdef __GNUC__
#define GNUC_ALIGN(n) __attribute__((align(n)))
#endif
ENUM(x) {
};
#ifdef _WIN32
#pragma pack(push)
#pragma pack(n)
#endif
STRUCT(x) {
} GNUC_ALIGN(n);
#ifdef _WIN32
#pragma pack(pop)
#endif
//===============================================================
//---------------------function----------------------------------
#ifdef __cplusplus
extern "C" {
#endif
DLL_API void CALLSPEC foobar();
#ifdef __cplusplus
}
#endif
//===============================================================
#endif // XXX_H
说明
防止头文件重复包含
msvc下可以使用#pragma once
这样的方式,但为了跨编译器,最好习惯如下通用形式
#ifndef XXX_H
#define XXX_H
#endif
Windows下导出dll说明
#if defined(DLL_EXPORTS)
#define DLL_API __declspec(dllexport)
#else
#define DLL_API __declspec(dllimport)
#endif // DLL_EXPORTS
Windows下如果需要使用静态库,需要添加#define XXX_STATIC
调用约定
#define CALLSPEC __stdcall
Windows API
接口一般使用__stdcall
调用约定(default is __cdecl
) __stdcall
和__cdecl
参数都是从右到左入栈,不同的是__stdcall
由函数自身管理栈,__cdecl
由调用者管理栈。
此为msvc x86
下__stdcall
生成的dll符号名会形如[email protected]
,需要加.def
文件强制命名。
def文件格式如下
LIBRARY "xxx"
EXPORTS
SdkInit @1
SdkCleanup @2
msvc可以使用dumpbin
命令查看dll的导出符号,使用lib
命令生成xxx.lib
动态链接库导入文件
dumpbin /exports xxx.dll
lib /def:xxx.def /mechine:ARM|ARM64|EBC|X64|X86 /out:xxx.lib
更详细的命令说明请直接在cmd下查看命令帮助
typedef struct
#define ENUM(x)
#define STRUCT(x)
宏定义ENUM
和STRUCT
的目的是给x
加上typedef
定义类型,使得C
能够和C++
一样能够直接使用x
,而不是struct x
这样繁琐的方式。
字节对齐
msvc和gnuc字节对齐的语法不同,msvc使用#pragma pack(n)
,gnuc使用__attribute__((align(n)))
#ifdef __GNUC__
#define GNUC_ALIGN(n) __attribute__((align(n)))
#endif
#ifdef _WIN32
#pragma pack(push)
#pragma pack(n)
#endif
STRUCT(x){
} GNUC_ALIGN(n);
#ifdef _WIN32
#pragma pack(pop)
#endif
上一篇: iOS 图片命名规则