Using #define'd constants in a C file via extern?

BlitzMax Forums/BlitzMax Programming/Using #define'd constants in a C file via extern?

Pineapple(Posted 2015) [#1]
I can't seem to find a way to get this to work. The best I've come up with is writing C functions that return the constants and setting them as globals in BlitzMax. But that's messy.


Brucey(Posted 2015) [#2]
I generally just create a list of Consts in BlitzMax which match the definitions, much like this :
Const FONT_STYLE_NORMAL:Int = 0
Const FONT_STYLE_OVERLINE:Int = 1
Const FONT_STYLE_UNDERLINE:Int = 1 Shl 1
Const FONT_STYLE_STRIKE_THROUGH:Int = 1 Shl 2
Const FONT_STYLE_BACKGROUND:Int = 1 Shl 3

The actual values are evaluated at compile time and replace the Const variables directly - similar to the way #defined values are in C.

Depending on the number of them, I generally run them through a regex to generate the BlitzMax code straight from C, so the code only takes a couple of minutes to write.


Pineapple(Posted 2015) [#3]
In this case, though, I'm trying to refer to constants that may be implementation-specific, e.g. FE_DIVBYZERO.


Yasha(Posted 2015) [#4]
Those are really your only options. #define doesn't create exportable values that exist at runtime; it works as a text replacement system before the C is compiled (hence the C "preprocessor"). No linkable object is generated with the name - if it's a constant, it just pastes the literal. Unusable by BlitzMax since it requires a source-level understanding of C, which Max doesn't have.

So the function approach is actually the best bet; as a way to wrap a non-linkable value inside a linkable one it actually seems fairly elegant to me. Writing a simple precompile step of your own to automatically generate the functions names and definitions, the Max-side globals and externs, and the assignment step, from a single centralised list of names, is probably the only way to reduce duplication while still keeping the platform checks C-side.


grable(Posted 2015) [#5]
Using global C variables works too, saves the function call overhead.
But you could allso wrap them all up in a struct and fill a type instance if polluting the global namespace is undesirable.


Pineapple(Posted 2015) [#6]
How would I wrap them in a struct and fill a type instance?


grable(Posted 2015) [#7]
How would I wrap them in a struct and fill a type instance?

Heres en example using signal defines, it uses bmx types to keep memory management on the blitzmax side.
But you could use extern types as well, and keep all memory on the C side.

signals.c

signals.bmx


Its more typing though, so id rather use globals myself. Or better still do as brucey and make constants in blitzmax via regex.
And if they are platform specific, i doubt they change that much and you could use ?win32 ?linux ?macos to fudge the differences.