kwc
1
I'm using Swift to call some functions in a C library, but some error messages showed when building these C headers.
In my C header, enum type imports value through #include, but Swift compiler shows some syntax errors. Here's the code snippet:
In error.h
enum error_code {
NOT_IMPL = -1,
#define ERROR_CODE(name, val) name = val,
#include "error_codes.h" // it makes some error
}
In error_codes.h
#ifdef ERROR_CODE
ERROR_CODE( OK, 0 )
ERROR_CODE( BAD_HANDLE, 1 )
#undef ERROR_CODE
#endif
My current solution is to move the code from error_codes.h to error.h without using C's include, but it has to modify the code.
Is there any other solutions without modifying the code?
jonprescott
(Jonathan Prescott)
2
Swift doesn't handle complex macros in C. Your ERROR_CODE macro is a complex macro.
kwc
4
But it is weird. In my C header, there are still some complex macros can be compiled. This is another complex macros code in C, but they can be compiled.
typedef struct ion_type *ION_TYPE;
#define ION_TYPE_INT(x) ((intptr_t) (x))
#define tid_BOOL ((ION_TYPE) tid_BOOL_INT)
#define tid_INT ((ION_TYPE) tid_INT_INT)
#define tid_BOOL_INT 0x100
#define tid_INT_INT 0x200
jonprescott
(Jonathan Prescott)
5
Those are not complex. Those are just type aliases. What makes you original macro complex is the value assignment. Swift's handling of C macros does not seem to allow procedural code substitution, even if it's not really procedural (you're defining an enum). The Swift compiler does not operate the same as the C-preprocessor, it's not just a strict text substitution pass like it is in C.
jrose
(Jordan Rose)
6
If you include error.h from Swift, it should work fine. Swift doesn't have to deal with ERROR_CODE directly. What's the actual error you're getting?
(EDIT: I have a suspicion, but I don't want to go down the wrong path if it's not that.)
kwc
7
mainly some parse and semantic issues
In ion_error.h
in ion_error_codes.h
jrose
(Jordan Rose)
8
Hmm. Well, it could still be what I'm thinking of, though those are some obtuse errors. Swift expects C libraries to be modules in the Clang sense, with a module map that's generated by Xcode or SwiftPM. But you can also provide one explicitly, which will let you mark ion_error_codes.h as a textual header, rather than one that's meant to be included directly. That'll look something like this:
module Ion {
umbrella header "ion.h"
textual header "ion_error_codes.h"
export *
module * { export * }
}
(If your library is being built as a framework, you should use framework module Ion instead of just module Ion.)
1 Like
kwc
9
I'll take a look about the module map part. Thanks for your reply!