I have a code which is compiled into a library (dll, static library and so). I want the user of this library to use some struct to pass some data as parameters for the library function. I thought about declaring the struct in the API header file.
- Is it safe to do so, considering compilation with different compilers, with respect to structure alignment or other things I didn’t think about?
- Will it require the usage of the same compiler (and flags) for both the library and its user?
Few notes:
- I considered giving the user a pointer and set all the struct via functions in the library, but this will make the API really not comfortable to use.
- This question is about C, although it would be nice to know if there’s a difference in c++.
If it’s a regular/static library, the library and application should be compiled using the same compiler. There’re a few reasons for this that I can think of:
You may, however, often use slightly different versions of the same compiler to compile the library and the application using it. Usually, it’s OK. Sometimes there’re changes that break the code, though.
You may implement some “initialization” function in that header file (declared as
static inline) that would ensure that types, type sizes, alignment and packing are the same as expected by the compiled library. The application using this library would have to call this function prior to using any other part of the library. If things aren’t the same as expected, the function must fail and cause program termination, possibly with some good textual description of the failure. This won’t solve completely the problem of having somewhat incompatible compilers, but it can prevent silent and mysterious malfunctions. Some things can be checked with the preprocessor’s#ifand#ifdefdirectives and cause compilation errors with#error.In addition, structure packing problems can be relieved by inserting explicit padding bytes into structure declarations and forcing tight packing (by e.g. using
#pragma pack, which is supported by many compilers). That way if type sizes are the same, it won’t matter what the default packing is.You can apply the same to DLLs as well, but you should really expect that the calling application has been compiled with a different compiler and not depend on the compilers being the same.