Share a cross-platform header file

I. Introduction

When we usually write code, especially when manufacturing wheels (providing library files for others ), we will encounter various demand scenarios:

  1. Some people need to use it under Linux system, some people need to use it under Windows system;
  2. Some people use C language to develop, some people use C++ to develop;
  3. Some people use dynamic libraries, some people use static libraries;

Especially in the Windows system, the exported function in the library file needs to use _declspec(dllexport) to declare the function, and the user needs to use _declspec(dllimport) to declare the function when importing , which is very troublesome!

This short article shares a header file . Using this header file, plus a few macros passed during compilation , you can perfectly handle the various needs just mentioned.

Second, the header file

Just upload the code directly, you can try to analyze it first, and then we will analyze different usage scenarios one by one .

The main purpose of this header file is to define a macro: MY_API , and then add this macro to the declaration of each function or class that needs to be exported in the library file . E.g:

void MY_API do_work();

Here is the header file:

_Pragma("once")

#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__)
    #define MY_WIN32
#elif defined(linux) || defined(__linux) || defined(__linux__)
    #define MY_LINUX
#endif

#if defined(MY_WIN32)
    #ifdef MY_API_STATIC
      #ifdef __cplusplus
         #define MY_API extern "C"
      #else
         #define MY_API
      #endif
   #else
      #ifdef MY_API_EXPORTS
         #ifdef __cplusplus
            #define MY_API extern "C" __declspec(dllexport)
         #else
            #define MY_API __declspec(dllexport)
         #endif
      #else
         #ifdef __cplusplus
            #define MY_API extern "C" __declspec(dllimport)
         #else
            #define MY_API __declspec(dllimport)
         #endif
      #endif
   #endif
#elif defined(MY_LINUX)
    #ifdef __cplusplus
       #define MY_API extern "C"
    #else
       #define MY_API
    #endif
#endif

Three, the predefined macro

Suppose you need to write a library file and provide it for others to use. After defining the above, the first document, other documents must include this header file.

1. Platform Macro Definition

Different platforms have predefined corresponding macro definitions, for example:

Windows platform: WIN32, _WIN32, WIN32 ;
Linux platform: linux, __linux, linux ;

On a certain platform, these macros may not all be defined, it is possible that only one of them is defined.

For unity, we unify these possible macros at the beginning of the header file, and define our own platform macro definition: MY_WIN32 or MY_LINUX. When we need to distinguish between different platforms later, we use this self-defined one. Platform macro .

Of course, you can continue to expand other platforms, such as: MY_MAC, MY_ARM, etc.

2. Compiler macro definition

If you use C++ when writing the library code , and the user uses the C language, then you need to make an extern "C" declaration for the library function , so that the compiler does not rewrite the name of the function .

The compiler g ++ predefined macro __cplusplus, therefore, in the header file, you use this macro in MY_APIadding the extern "C" statement.

Fourth, Windows platform scenario analysis

1. Compile and generate library files

(1) Generate static library

In the static library, no __declspec(dllexport/dllimport)statement, it is only necessary to distinguish compiler (gcc or g ++), define the macro compiler options MY_API_STATIC, you can get the final MY_APIare:

gcc compiler: #define MY_API
g++ compiler: #define MY_API extern “C”

(2) Generate dynamic library

In compiling options, define macros MY_API_EXPORTS, so the resulting MY_APIbecomes:

gcc compiler: #define MY_API __declspec(dllexport)
g++ compiler: #define MY_API extern “C” __declspec(dllexport)

2. Use the library

In using the library application, also you need to include this code in the header file, and then add a variety of macro compiler options defined, to generate the corresponding MY_APImacro definitions.

(1) Use static library

Needs to be defined at compile options MY_API_STATIC, you can get the final MY_APIare:

gcc compiler: #define MY_API
g++ compiler: #define MY_API extern “C”

(2) Use dynamic library

Does not require any macro defined at compile options, you can get the final MY_APIare:

gcc compiler: #define MY_API extern “C” __declspec(dllimport)
g++ compiler: #define MY_API __declspec(dllimport)

This is equivalent to declaring the import library function.

Five, Linux platform scenario analysis

It's much simpler under the Linux platform, you only need to pay attention to the problem of the compiler, and there is no distinction between exporting and importing.


Good articles should be forwarded ; the more you share, the luckier you are!


Recommended reading

1. C language pointer-from the bottom-level principle to fancy skills, use graphics and code to help you explain thoroughly
2. The original gdb bottom-level debugging principle is so simple
3. Step by step analysis-how to use C to implement object-oriented programming
4. All said The software architecture needs to be layered and divided into modules, and what should be done specifically (1)
5. It is said that the software architecture needs to be layered and divided into modules, and what should be done specifically (2)

Guess you like

Origin blog.csdn.net/u012296253/article/details/115366952