I am working on a GLCD library for embedded devices. The idea is to split it into highlevel and lowlevel section. This allows the "user" to just write the lowlevel functions for his display controller, and use the highlevel functions like line-, cricle-, string drawing etc. without rewriting these functions.
To keep things easy, I decided that the user of the library just has to do the following, for example to use a display with SSD1289 controller, in his main.c:
#define LCD_USE_SSD1289
Example file ssd1289_lld.h:
#ifdef LCD_USE_SSD1289
lld_lcdInit(void);
#endif
Example file ssd1289_lld.c:
lld_lcdInit(void) {
// do some stuff for this controller
}
Example file s6d1121_lld.h:
#ifdef LCD_USE_S6D1121
lld_lcdInit(void);
#endif
Example file s6d1121_lld.c:
lld_lcdInit(void) {
// do some stuff for this controller
}
Inside the highlevel file, I'll just do:
#include "drivers/ssd1289_lld.h"
#include "drivers/s6d1121_lld.h"
void lcdInit(void) {
lld_lcdInit();
}
But this does somehow not work:
When I don't do any #define LCD_USE_SSD1289 it does work without any problems
After adding a second driver for a different type of controller, it still work without defining any type, and it also works when I define the wrong controller type.
What am I doing wrong?
Make sure the preprocessor puts the #ifdef LCD_USE_SSD1289 after the #define LCD_USE_SSD1289 area. You said #define LCD_USE_SSD1289 was in the main.c file. You should really use a separate definitions.h file that is #included at the top of ssd1289_lld.h. Hope that helps.
Related
I'm fairly new to programming in C. My problem is that I have two implementations of a function and I want to be able to switch between them easily.
Right now I define the two implementations of the function as function_implementation1 and function_implementation1 in the files "funtion_implementation1.h" and "funtion_implementation2.h" respectively. To switch between them I have the following file:
#define IMPLEMENTATION1
#ifdef IMPLEMENTATION_1
#include "funtion_implementation1.h"
#define myFunction function_implementation1
#endif
#ifdef IMPLEMENTATION_2
#include "funtion_implementation2.h"
#define myFunction function_implementation2
#endif
In order to switch from one implementation to the other I just have to change the first line. This approach works, and I was satisfied with it for a while, but now it is bugging me that I have to open this file so often. I have a parameters.h file where I define all my parameters and I would rather choose which implementation to use in that file. Sadly, moving the first line to that file does not work. If I do that myFunction is not defined.
What is the best way to do this?
you should include your parameters file where you use alias, macros, etc:
#include "Parameters.h"
also, all your headers files should start with:
#ifndef __FILE_H__
#define __FILE_H__
// definitions go there
#endif
This prevents nested include of header files
Use preprocessor options, specifically the -D option. If you wanted to use IMPLEMENTATION1, when you are compiling that file on the command line (or in IDE), add -D IMPLEMENTATION1. This defines that macro. Same works for any macro
I am writing a simple c test framework. For simplicity, I only provide a single header file (containing all the function definitions), but I meet some problems. If I only include the header once, everything works fine. If I include the header twice, the gcc linker report duplicate symbol error (that is normal), so I add static prefix in every function in the header. This time it works, but the function is duplicate in the final binary. See bellow:
[heidong#HEIDONGVM ztest]$ nm m | grep __ct_hex_dump
0000000000400904 t __ct_hex_dump
0000000000401efc t __ct_hex_dump
Is there some way the made the function define only once?
Thanks a lot!!
Maybe someone needs the code, I just started a project in github: https://github.com/buf1024/test
Thanks again!!
What you have is in ct.h
static functions
static function definitions
In atest.c
// This is the first lot of definitions
#include "ct.h"
In main.c
// This is the second lot of definitions
#include "ct.h"
To fix
move the static function definitions to ct.c, remove the word static
Change all the prototypes in ct.h from static to extern
add ct.c to your link.
Edit: just delivering just ct.h
Change all the prototypes in ct.h from static to extern
Before the first function body add #ifdef __CT_C__
After the last function, add #endif
Tell the user that in the code that contains main, they need to #define __CT_C__ before they #include "ct.h"
Anything else that #include "ct.h" must not define __CT_C__.
Use compiler directives.
#IFNDEF MYFUNC
#DEFINE MYFUNC
myfunc();
#ENDIF
Everytime the compiler hits this directive, it will only go in once when MYFUNC is not defined and after defining it, it won't go in the statement again. No matter how many times you include the header file, it will always check if it's been defined before.
Coppiler directives is not part of the compiled code. It's just a directive.
If you absolutely need only one file, you can do it with preprocessor:
header.h
#ifndef HEADER_H
#define HEADER_H
#ifdef IMPLEMENT
#undef IMPLEMENT
void func(void) {
...
}
#else
void func(void);
#endif
#endif
In one file:
// Define
#define IMPLEMENT
#include "header.h"
In other files:
// Only declarations
#include "header.h"
Though I would choose a proper .c file instead.
I want to include the result of a macro expansion. It seems include only knows <> ""?
This fails:
#define audio sinwave
#ifdef audio
#include audio".c"
/*#include "sinwave.c"*/
#endif
But this works:
#ifdef audio
if(i==0){set_audio((char *)audio);return;}
#endif
You could do something like this:
#define audio audio
#define FF(X) #X
#define F(X) FF(X.c)
#ifdef audio
#include F(audio)
#endif
that is you'd have to append the .c before you place everything into a string. The usual concatenation "audio" ".c" -> "audio.c" of adjacent strings happens in a later compilation phase than preprocessing, so an #include directive cannot deal with this.
No. Preprocessor directives cannot be used like this. You can use macros to concatenate and stringify names, but that's another case. If you need this, you should most probably re-think your design because it's not good enough at the moment.
Maybe it's not clear to me... But I see a few different questions that you're asking...
I think your asking if you can include source files, yes you can, but its not the best idea; see here for a good discussion why.
If you're wondering about including files with "..." vs <...>, the difference is the quotes are when files are in your local directory (or you want to include the path to the file) the <> are for when the file is in your search path.
If you want to stringify the file name, then
Jens Guestedt answer is what you want... But I question the logic behind doing this...
Why not include the .c file in your project normally (add it to your makefile or whatever) then just wrap the code in question (or the while file) in the #ifdef? That's a much more standard way to conditionally compile the code.
I have several C scripts that will all have the same format(functions), but occasionally the actual code within a few functions. I am trying to separate a function into an external header file, but the issue is this:
int FunctionImExtracting()
{
//some code
FunctionThatCannotBeExtractedButTheFunctionSignatureWillAlwaysRemainTheSame()
//more code.
};
I have a feeling that function pointers will be my friend here, but I'm not sure how. How can this be accomplished?
You don't (normally want to) put the function itself into a header -- you just want to put a declaration of the function in the header, so other files can include the header and be able to call that function:
//myfunc.h:
#ifndef MY_HEADER_H_INCLUDED
int FunctionImExtracting(void);
#define MY_HEADER_H_INCLUDED
#endif
// myfunc.c:
#include "theirheader.h"
#include "myfunc.h"
int FunctionImExtracting() {
// as in question
}
You will need a header file with the declaration of FunctionThatCannotBeExtractedButTheFunctionSignatureWillAlwaysRemainTheSame(). Then in the file to which you are exporting, you'll need to include this header. And the actual definition of FunctionThatCannotBeExtractedButTheFunctionSignatureWillAlwaysRemainTheSame() can still be in the file from which you exported FunctionImExtracting().
Did I get your problem right?
I'm writing a C++ plugin in Mac OS X using the Carbon framework (yeah, yeah, I know, Apple is deprecating Carbon, but at the moment I can't migrate this code to Cocoa). My plugin gets loaded by a master application, and I need to get a CFBundleRef reference to my plugin so that I can access it's resources.
The problem is, when I call CFBundleGetMainBundle() during my plugin's initialization routines, that returns a reference to the host's bundle reference, not the plugin's. How can I get a reference to my plugin's bundle instead?
Note: I would rather not use anything determined at compile-time, including calling CFBundleGetBundleWithIdentifier() with a hard-coded string identifier.
See this posting on the carbon-dev mailing list, which seems to be a similar situation.
The method given there is
I recommend using CFBundleGetBundleWithIdentifier.
Your plug-in should have an unique identifier; something like
"com.apple.dts.iTunes_plug-in", etc. Look for the CFBundleIdentifier
property in your plug-in's bundle's info.plist.
Note: I would rather not use anything determined at compile-time, including calling CFBundleGetBundleWithIdentifier() with a hard-coded string identifier.
Because that's WET, right?
Here's how you can make that solution DRY.
First, define some macros for this in a header file, like so:
#define MY_PLUGIN_BUNDLE_IDENTIFIER com.example.wiflamalator.photoshop-plugin
#define MY_PLUGIN_STRINGIFY(x) #x
#define MY_PLUGIN_BUNDLE_IDENTIFIER_STRING MY_PLUGIN_STRINGIFY(MY_PLUGIN_BUNDLE_IDENTIFIER)
Import the header file into the code that calls CFBundleGetBundleWithIdentifier. In that code, use CFSTR(MY_PLUGIN_BUNDLE_IDENTIFIER_STRING).
Then, in Xcode, either set that file as your Info.plist prefix header, or (if you already have one) #include it into that header. Finally, in Info.plist, set the bundle identifier to MY_PLUGIN_BUNDLE_IDENTIFIER (in a string value, of course).
Now you have the bundle identifier written in exactly one place (the header), from which the C preprocessor puts it in all the places where it needs to be, so you can look up your own bundle by it using CFBundleGetBundleWithIdentifier.
#ifdef __APPLE__
#include "CoreFoundation/CoreFoundation.h"
#endif
#ifdef __APPLE__
// This should be actually defined somewhere else
#define MY_PLUGIN_BUNDLE_IDENTIFIER com.yourbundle.name
// Then all the regular stuff
#define QUOTE(str) #str
#define EXPAND_AND_QUOTE(str) QUOTE(str)
#define MY_PLUGIN_BUNDLE_IDENTIFIER_STRING EXPAND_AND_QUOTE(MY_PLUGIN_BUNDLE_IDENTIFIER)
CFBundleRef mainBundle = CFBundleGetBundleWithIdentifier(CFSTR(MY_PLUGIN_BUNDLE_IDENTIFIER_STRING));
CFURLRef resourcesURL = CFBundleCopyResourcesDirectoryURL(mainBundle);
char path[PATH_MAX];
if (!CFURLGetFileSystemRepresentation(resourcesURL, TRUE, (UInt8 *)path, PATH_MAX))
{
// error!
}
CFRelease(resourcesURL);
chdir(path);
StoragePaths::setApplicationResourcesDirectory(STR(path));
#endif
Prints the path to the your bundle
Note: For JUCE users, use JucePlugin_CFBundleIdentifier instead of MY_PLUGIN_BUNDLE_IDENTIFIER and you're all set