c接口跨平台头文件模板

源码模板

#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 CALLCONV __stdcall
#else
    #if __GNUC__ >= 4
        #define DLL_API __attribute__((visibility("default")))
    #else
        #define DLL_API
    #endif
    #define CALLCONV
#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 CALLCONV func1();

#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 CALLCONV __stdcall

Windows API接口一般使用__stdcall调用约定(default is __cdecl)
__stdcall__cdecl参数都是从右到左入栈,不同的是__stdcall由函数自身管理栈,__cdecl由调用者管理栈。
此为msvc x86__stdcall生成的dll符号名会形如_func@4,需要加.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)

宏定义ENUMSTRUCT的目的是给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

猜你喜欢

转载自blog.csdn.net/GG_SiMiDa/article/details/81329762