I'm looking for a good technical solution to doing DI in C.
I have seen some of the DI questions here already, but I haven't seen one with any actual examples or concrete implementation suggestions.
So, lets say we have the following situation:
We have a set of modules in c; we want to refactor those modules so that we can use DI to run unit tests and so on.
Each module effectively consists of a set of c functions:
module_function(...);
Modules depend on each other. Ie. Typically you may have a call such as:
int module1_doit(int x) {
int y = module2_dosomethingelse(x);
y += 2;
return(y);
}
What is the correct approach to DI for this?
Possible solutions seem to be:
(1) Using function pointers for all module functions, and when invoking a function do this (or similar):
int y = modules->module2->dosomethingelse(x);
(2) Compile multiple libraries (mock, std, etc.) of with the same symbols and dynamically link in the correct implementation.
(2) seems to be the correct way of doing it, but is difficult to configure and annoyingly forces you to build multiple binaries for each unit test.
(1) Seems like it might work, but at some point your DI controller is going to get stuck in a situation where you need to dynamically invoke a generic factory function (void ( factory) (...) say) with a number of other modules that need to be injected at runtime?
Is there another, better way of doing this in c?
What's the 'right' way of doing it?
I don't see any problem with using DI in C. See:
http://devmethodologies.blogspot.com/2012/07/dependency-injection.html
I've concluded that there is no 'right' way of doing this in C. It's always going to be more difficult and tedious than in other languages. I think it's important, however, not to obfuscate your code for the sake of unit tests, though. Making everything a function pointer in C may sound good, but I think it just makes the code horrific to debug in the end.
My latest approach has been to keep things simple. I don't change any code in C modules other than a small #ifdef UNIT_TESTING at the top of a file for externing and memory allocation tracking. I then take the module and compile it with all dependencies removed so that it fails link. Once I've reviewed the unresolved symbols to make sure they are what I want, I run a script that parses these dependencies and generates stub prototypes for all the symbols. These all get dumped in the unit test file. YMMV depending on how complex your external dependencies are.
If I need to mock a dependency in one instance, use the real one in another, or stub it in yet another, then I end up with three unit test modules for the one module under test. Having multiple binaries may not be ideal, but it's the only real option with C. They all get run at the same time, though, so it's not really a problem for me.
This is a perfect use-case for Ceedling.
Ceedling is sort umbrella project that brings together (among other things) Unity and CMock, which together can automate a lot of the work you're describing.
In general Ceedling/Unity/CMock are a set of ruby scripts that scan through your code and auto-generate mocks based on your module header files, as well as test runners that find all the tests and makes runners that will run them.
A separate test runner binary is generated for each test suite, linking in the appropriate mock and real implementations as you request in your test suite implementation.
I was initially hesitant to bring in ruby as a dependency to our build system for testing, and it seemed like a lot of complexity and magic, but after trying it out and writing some tests using the auto-generated mocking code I was hooked.
A little late to the party on this but this has been a recent topic where I work.
The two main ways that I've seen it done is using function pointers, or moving all dependencies to a specific C file.
A good example of the later is FATFS.
http://elm-chan.org/fsw/ff/en/appnote.html
The author of fatfs provides the bulk of the library functions and relegates certain specific dependencies for the user of the library to write (e.g. serial peripheral interface functions).
Function pointers are another useful tool, and using typedefs help to keep the code from getting too ugly.
Here's some simplified snippets from my Analog to Digital Converter (ADC) code:
typedef void (*adc_callback_t)(void);
bool ADC_CallBackSet(adc_callback_t callBack)
{
bool err = false;
if (NULL == ADC_callBack)
{
ADC_callBack = callBack;
}
else
{
err = true;
}
return err;
}
// When the ADC data is ready, this interrupt gets called
bool ADC_ISR(void)
{
// Clear the ADC interrupt flag
ADIF = 0;
// Call the callback function if set
if (NULL != ADC_callBack)
{
ADC_callBack();
}
return true; // handled
}
// Elsewhere
void FOO_Initialize(void)
{
ADC_CallBackSet(FOO_AdcCallback);
// Initialize other FOO stuff
}
void FOO_AdcCallback(void)
{
ADC_RESULT_T rawSample = ADC_ResultGet();
FOO_globalVar += rawSample;
}
Foo's interrupt behavior is now injected into the ADC's interrupt service routine.
You can take it a step further and pass a function pointer into FOO_Initialize so all dependency issues are managed by the application.
//dependency_injection.h
typedef void (*DI_Callback)(void)
typedef bool (*DI_CallbackSetter)(DI_Callback)
// foo.c
bool FOO_Initialize(DI_CallbackSetter CallbackSet)
{
bool err = CallbackSet(FOO_AdcCallback);
// Initialize other FOO stuff
return err;
}
There are two approaches that you can use. Whether you really want to or not, as Rafe is pointing out, are up to you.
First: Create the "dynamically" injected method in a static library. Link against the library and simply substitute it during tests. Voila, the method is replaced.
Second: Simply provide compile-time replacements based on preprocessing:
#ifndef YOUR_FLAG
/* normal method versions */
#else
/* changed method versions */
#endif
/* methods that have no substitute */
Related
I am making a low level library that requires initialization to work properly which I implemented with a init function. I am wondering if there is a way to make the init call be called once the user calls a library function ideally without:
Any overhead
No repeated calls
No exposed global variables. (my current solution does this, which I don't quite like)
my current solution as per comment request:
bool isinit = 0;
void init()
{
isinit = 1;
// init code
}
void lib_function()
{
if(!isinit) init();
// function code
}
The compiler seems to be smart enough (using -0fast on gcc) to not make that comparison each time a lib_function is called, but this still exposes a global variable which I don't like.
Best way to abstract away an init function?
Surely your library has some state. Typically, a library exposes functions that work on a specific structure. Do not use global variables - do not write spaghetti code. Expose the structure that holds the state of your library, and make all functions of your library take a pointer to the structure as an argument. Use a namespace - prepend all exported symbols with a prefix. An init function is just like int lib_init(struct lib_the_struct *t); - it will be self-understandable that users need to initialize the structure with that function before use. For example: fopen(), pthread_create.
Write an init function in your library. Write clear documentation stating, that the user of your library has to call the function once before calling any other function. For example: https://curl.se/libcurl/c/curl_global_init.html .
If you're happy with a solution that is a common extension rather than part of the C standard, you can mark your init function with the constructor attribute, which ensures it will be called automatically during program initialization (or during shared library load if you eventually end up using that).
I would fix this with assert so that the if will dissappear in release build and if you forget to call the init_function somewhere you get the error while developing.
Also turn isinit into a static so every library can have its own variable with the same name.
#include <assert.h>
#ifndef NDEBUG
static int isinit = 0;
#endif
void lib_function()
{
assert(isinit && "library: init not called");
}
There will be overhead if you run if(!isinit) init(); each time you call a function. At least an extra branch.
As for removing global variables, do in your example but static bool isinit = 0;. This reduces the scope of the variable to the local translation unit (.c file and all .h files it includes). It's no longer "global". Note that this isn't ideal in multi-threaded scenarios - you will have to protect the variable with a mutex then.
Overall though, what you are trying to do isn't a good idea. It is very common convention for C libraries to have an init function and the user of the library is expected to call it before calling anything else or they are to blame, not your library. Naturally you have to make this clear to them with source code documentation. It is common to have a list of prerequisites in source code comments together with every function declaration placed in the header file of the library.
I have some code in C which does some hardware access. This code is ready and well tested. Now I want to implement a web interface for controlling this hardware. So I came along PHP extension development with Zephir.
My question is, „Is it possible with Zephir to include an external library resp. link against it?“ and if it is possible, how can I do it?
Yes, it's possible and there are two approaches for working with C-code.
By wrapping C-code in CBLOCKs
You can embed c-code in tags, like so: %{ // c-code }%.
This feature is undocumented, but exists in the tests.
https://github.com/phalcon/zephir/blob/master/test/cblock.zep
https://github.com/phalcon/zephir/blob/c47ebdb71b18f7d8b182f4da4a9c77f734ee9a71/test/cblock.zep#L16
https://github.com/phalcon/zephir/blob/c47ebdb71b18f7d8b182f4da4a9c77f734ee9a71/ext/test/cblock.c
%{
// include a header
#include "headers/functions.h"
// c implementation of fibonacci
static long fibonacci(long n) {
if (n < 2) return n;
else return fibonacci(n - 2) + fibonacci(n - 1);
}
}%
Looks a bit ugly, but works ,) A bit more elegant, but also more work, are custom optimizers:
By writing a custom optimizer
An ‘optimizer’ works like an interceptor for function calls. An
‘optimizer’ replaces the call for the function in the PHP userland by
direct C-calls which are faster and have a lower overhead improving
performance.
It's possible to write an optimizer with a clean interfaces, allowing Zephir to know the parameter type passed forward to the C-function and the data type returned.
Manual: https://docs.zephir-lang.com/en/latest/optimizers.html
Example (call to fibonacci c-func): https://github.com/phalcon/zephir/pull/21#issuecomment-26178522
I've noticed that in a lot of library, version informations, as well as informations on the availability of special features that may differ or be absent depending on the build, are made accessible to client applications not by a constant, but by a function call returning a constant, e.g.:
const char *libversion(void) {
return "0.2";
}
bool support_ssl(void) {
return LIB_SSL_ENABLED; /* whatever */
}
instead of simply:
const char *libversion = "0.2";
bool support_ssl = LIB_SSL_ENABLED;
Is there a practical reason for doing this, or is it only some kind of convention?
Is there a practical reason for doing this, or is it only some kind of convention?
I'd say both…
A practical reason I see for this, is that when you distribute your library, your users install a compiled version of it as a shared object, and access its data using the header. If the constant is accessible through a function, its prototype is declared in the header, but the value is defined in the compilation unit, linked in the shared object file. Edit: I'm not saying it's not possible, but a good reason for doing so is to keep the possibility to keep the API stable, while switching from a constant value to a calculated value for a given function, cf reason #3.
Another practical reason I can see is that you could access that API using some sort of "middleware", like corba, that enables you to access functions, but not constants (please be kind with me if I'm wrong about that particular point, I haven't done any CORBA in 10 years…).
And in the end, it's somehow good OOP convention, the header file being a pure functional interface, and all the members being encapsulated enabling a full decoupling of the inner workings of the library and the exposed behaviour.
Hope someone can help - apologies for this very basic question, but I'm using standard C to write code for some experiments with PIC microcontrollers, and I'm very new to the C Language.
I have various logical groups of code, such as functions to control an LCD display, that I'd like to make re-usable to PIC-based projects and would like to know how best to break-up these logical code groups for re-usability.
In the example of the LCD functions, I presume I split the declarations into a header named 'lcd.h' (including in 'Header Files' project directory of my IDE) and the function definitions in an include 'lcd.c' (including in 'Source Files' project directory of my IDE) - would this be correct?
What are the naming conventions for breaking up code in this way? For instance should all global declarations be in a header file named 'main.h'?
Many thanks,
Alex
It's good that you are focusing on modularity. Not only will it bring you re-usability, but it will also make debugging easier.
Naming convention
You are correct. For LCD functions, create the files lcd.c and lcd.h. There are no universal function naming conventions, but here's what I use:
lcd.h:
void LCD_PublicFunction(void);
lcd.c:
static void PrivateFunction(void);
void LCD_PublicFunction(void)
{
// Function goes here
}
static void PrivateFunction(void)
{
// Function goes here
}
I place a LCD_ prefix in front of all my public functions in order to prevent namespace collisions and also to help me find the location of a function at any point. The static keyboard prevents any functions outside of lcd.c from seeing PrivateFunction and I drop the prefix to denote private.
Globals
Please avoid global variables. As your project grows, it will become harder to trace the logic. Instead, use getter and setter functions.
static int brightness;
void LCD_SetBrightness(int var)
{
brightness = var;
}
int LCD_GetBrightness(void)
{
return brightness;
}
This gives you more flexibility. Perhaps you'll need to add a little logic each time the brightness is set. Perhaps you want the variable to be read-only, so you can drop the setter.
Granularity
Try to break up your project as much as possible. I'm assuming you'll be using some sort of serial port to communicate with the LCD. Break up the communications firmware from the LCD display firmware.
For instance, if it uses SPI, then you should create an spi.c and a spi.h.
I've seen this practice go too far. I've seen people wrap functionality around all of the I/O ports such that they have functions to set digital pins high and low.
Bad example:
void IO_PortA7 (char val)
{
LATAbits.LATA7 = val;
}
I haven't really gained anything here other than adding some syntactic sugar. Simply use LATAbits.LATA7 in the code since it's the standard way to turn I/O on and off on a PIC.
Good example:
void FX_SetBuzzer (char is_active)
{
LATAbits.LATA7 = is_active;
}
Just by reading the code, you can tell that I've connected a buzzer to pin A7. Furthermore, the rest of the code doesn't care how I've connected the buzzer, and there's only one change I have to make if I have to move the buzzer to a different pin. Finally, by using a variable name of is_active, I document the fact that the buzzer is active-high. I try to use questions for all boolean variable to remember what happens in the true condition.
Testing
Finally piece of advice. In each of your .c files, create a test harness.
#ifdef LCD_TEST
int main(void)
{
// Enable LCD communication.
LCD_Init();
// Display friendly greeting.
LCD_Display("Hello, world!");
// Wait for power-down.
for(;;);
}
#endif
This way, you can build a tiny program that tests your LCD by itself. It serves several purposes.
It follows Test-driven_development, which is a Good Thing.
It provides a basic form of documentation by showing a functional example.
In the future, your LCD might suddenly stop working. Simply invoke this code and see what happens. If the test works, you know your latest changes broke the LCD functionality somehow. If it doesn't, you know the problem is with the LCD itself or the connections between it and the PIC.
Good luck!
Is there any way to programmatically mock a function for a embedded c application, running on linux. In below example I want to mock main to call someBlah instead of someFunc in run-time.
#include <stdio.h>
void someFunc( void )
{
printf("%s():%d\n",__func__,__LINE__);
}
void someBlah( void )
{
printf("%s():%d\n",__func__,__LINE__);
}
int main(void)
{
someFunc();
}
The program will be executing from ram in Linux so text segment should be modifiable. I know GDB works on some similar concept where breakpoints code locations are replaced by trap instructions.
Sure, just make a table of function pointers.
#define BLAH 0
#define FOO 1
void (*table_function[])(void) = {someBlah, someFoo};
If they all have the same interface and return type, you can just switch them by switching table entries.
Then you call a function by performing
table_function[BLAH]();
If you want to swap a function, just say
table_function[BLAH] = otherBlah;
Also: don't do this unless you are writing some kind of JIT-compiling environment or a VM, usually you don't need such constructs and if you need them you are probably having a bad architecture day.
Although if you're experienced in OO design you can design polymorphic constructs in C that way (ignore this if that doesn't make sense).
You could always make some part of the text segment modifiable by an appropriate call to mprotect and overwrite some code with your own (e.g. by generating machine code with libjit, GNU lightning, ... or manually).
But using function pointers is a cleaner way of doing that.
If the functions are inside a shared library, you could even overwrite its Procedure Linkage Table (see also the ABI spec, which depends upon the architecture - here is one for ARM)
There are a few mocking frameworks for C.
At work, we've had some success with cgreen but we did have to make changes to its internals. Luckily, it's quite small, and so relatively easy to extend. An alternative that looks good, but I haven't worked with, is a combination of Unity and CMock.
On the general topic of unit testing embedded C code, I highly recommend Test Driven Development for Embedded C.
Another way I have done this is:
#include <stdio.h>
#define DEBUG
void someFunc( void )
{
#ifndef DEBUG
printf("%s():%d\n",__func__,__LINE__);
#else
printf("%s():%d\n",__func__,__LINE__);
#endif
}
int main(void)
{
someFunc();
}
Take a look at CMocka, there is an article about mocking on LWN: Unit testing with mock objects in C