User defined #defines in to a library

I am working on "libraryising" some code I've written. The idea is to create a library which can then be used wherever required, in a wide variety of projects. I plan to share the library at some point too.

However I need a way to get user-supplied (meaning from the ino file, the idea being that a user should have no need to edit the hfile or cpp file when in use) #defines. I need #defined values to pass from the top of the ino file, in to the library code.

This would work with a h file library, but I don't want that, I want to have the library in its own cpp file as a separate compilation unti from the main ino code.

I must use #defines, NOT, passing of variables as arguments, because for the functions I've written in the library to run at their proper speed certain variables (pin numbers used in port manipulation operations for example) must be constants. I have verified this on an oscilloscope, the code runs something like 5 times faster when #define or const uint8_t is used for certain variable names, compared to the slow case where a variable is used and the code has to perform certain if loops and switch cases on variable value at run time.

These #defines are constant for any given arduino system built, but the values may vary for different applications, so while they don't need to be actual variables (they will never vary during operation) (and must not be for speed reasons), they also can't be #defines contained in the library's h file or cpp file, as when the library is used for different projects different values will be needed.

But when different compilation units are used, a #define in the ino file doesn't seem to be accessible by the cpp file, I get compiler errors.

I would also like to have the library generate a compiler error with a custom message if these #defines are undefined or if they meet certain properties. For example, refusing to compile and giving a message "ERROR, pins PinAlpha, PinBeta, PinGamma and PinDelta must all be defined, and PinAlpha...PinDelta MUST all be different values" if one of those names isn't defined in the ino file, or if PinBeta and PinGamma were equal values. With other error messages available like "ERROR, defined value Epsilon must be between 2 and 25" if the ino file contained something such as #define Epsilon 30 .

I would be ok with a requirement that in the ino file the #defines must be writen above where the #include command sits.

What is the best way to proceed?

Thank you

This is not possible. And even if you could (e.g. by creating a header-only library), it would be a terrible idea and an ODR nightmare to have macros in user code affect your library.

What you can do is pass all the constants as template parameters to the respective functions and classes of your library.
It would either need to be a header-only library, or you'll have to instantiate all necessary parameter combinations in your .cpp file.

Why?

The requirements that you've outlined are impossible to achieve.

PieterP Why?
Because whilst I'd like these compile time #defines to be passed in by the user, I'd also like the library to be able to contain internal static variables kept safe from being changed by the user code in the ino function butable to be changed by the library's own functions.

That is PieterP's "good one"?

How does this ensure that in the library the passed info is seen as #defined type values, constants, and not interpreted as variables? Because it is crucial in my use case that these values are fixed at compile time so that during compilation various if loops and switch cases in the library code get collapsed down by use of "#defin es"/"const uint8_t s"?

If it manages this, then please give me a link to some examples of this being done.

Thank you

Templates are completely resolved at compile time.

pass a constant on object creation or use templates.

Ok, thank you. Can you point me to some examples of:

using templates and parameters
and
passing a constant on object creation

So I can have a go with them, and see if they let the code run as fast as #defines do.
Thank you

either search for "c++ initializer list" or make a short sketch with a class and a #define like you do today and some can change it accordingly ..

Post an example of the code you're talking about. Your description of what you want is far too vague to provide useful guidance.

2 Likes

No, initialize constant class member doing a different way than variable one.

This topic was automatically closed 180 days after the last reply. New replies are no longer allowed.