Global variable in a different library, C - c

I am trying a global variable to hold my error message in C.
One library called Utils has:
#ifndef private_error_h
#define private_error_h
extern char error[1024];
__declspec(dllexport) void FillError(char* newError);
#define GetErr() error
#endif
File error.c:
#include "private_error.h"
char error[1024];
void FillError(char* newError) {
// ...
}
Then I try to use it in a program:
#include "private_error.h"
int main() {
FillError("General error");
printf("%s\n", GetErr());
return 0;
}
It creates two variables with different addresses. How can I make the program use the variable from the Utils library?
I did manage to bypass this problem by changing GetErr to a function returning the string, but I am still wondering where the error is here.

You have to declare it in your header file as
extern char error[];
and in your code file (.c file) , declare it
char error[1024];
You are allocating it twice

Why not use function like this:
in .h:
char* GetErr();
and in .cpp:
char* GetErr() { return error; }
Try to avoid global variables. In file scope its pretty safe, but if you try to use it trough many files it can cause big errors.

Related

global static(or non-static?) char array(buffer) with access from all c files

I have a header file , "temp.h" ,and several ".c" files which has "#include <temp.h>" header statements in each of them. And I define a global static char array in "temp.h" file as follows:
temp.h
static char buffer[1000]={'A','B','C','\0'};
main.c
...
#include <temp.h>
int main()
{
strcpy(buffer,"xyz");
printf("\nBuffer : %s",buffer);
func();
return 0;
}
other.c
...
#include <temp.h>
int func()
{
printf("\nInside func(), buffer : %s",buffer);
return 0;
}
and I compile all files with following command:
gcc -o output.o main.c other.c
And I get no errors... and when run the "output.o" program ,
I expect a result like this:
Buffer : xyz // Buffer was intentionally changed inside main
Inside func(), buffer : xyz
but I get:
Buffer : xyz // Buffer was intentionally changed inside main
Inside func(), buffer : ABC // doesn't get updated buffer content- why?
Why when I change the contents of a "(supposedly)global" static char array in one file inside any function scope (main or anyother), this change doesn't get reflected to all this char array's future references from any other file later, but instead in each file((or maybe inside in each function) its content is preserved??
How to make such that, I can use a specific part of char array (memory region) which is GLOBALLY accessible from all "files" and in their functions, and all references get correct readings?
thnx
With your current approach you have two copies of the array. Instead you need to declare the array in temp.h (with extern instead of static) and define it elsewhere, for instance in in temp.c:
temp.h:
#ifndef TEMP_H
#define TEMP_H
extern char buffer[1000];
#endif
temp.c:
#include "temp.h"
char buffer[1000] = "ABC";
You can also probably find a more descriptive name than temp for the module. It is also a good idea to add a prefix to the buffer variable, e.g. temp_buffer so that you avoid potential name clashes and make it easier for yourself and others to find where the array is declared.
Ok...GOT IT!... now I solved!
In a singly included header file (( which is temp.h in question )) u must write:
extern char buffer[];
Note: single inclusion of this temp.h file can be achieved by "#ifndef-#endif" pairs in other ".c" and ".h" files of the compilation.
And next, include only in one of the files the following statement of definition:
char buffer[1000];
I hope this solution helps some guys.

Calling inline functions from file in C

Basically, I have a FileA.c:
//FIleA.c
void inline something()
{
//short code here
}
void inline another()
{
//short code here
}
Now I want to call these inline functions in another file main.c without using a header file.
How should I declare the prototypes of these functions in main.c?
//main.c
#include "FileA.c"
void something();
void another();
// or ???
int main()
{
something();
another();
something();
another();
return 0;
}
This answer actually suggests that there's no possible use case for defining inline functions in another .c file in this way.
On the other hand, if you #include "FileA.c" in your main file anyway, then you don't need to do anything, because you are using a header file (ending the name of an included file with .c doesn't change what it fundamentally is, it just confuses people reading your code).

How should I organize this C project

I am doing this programming assignment in C. But I am confused as to how to organize it.
So, here is the situation. I have two tree implementations and declare their struct/includes/function prototypes and so on in two separate header files. Then I have two c source code for the two implementations. Now here comes the problem. I have one test c file (only one main function for running tests) for the ADTs of Trees. Since the two implementations are going to use the same test. How can I avoid making two copies of the same main.c file? when I include the header file of tree implementation1, I can do gcc Tree_implementation1.c main.c. But to do implementation2, I have to got back in the main source file and manually change the include to tree implementation2, and then I can use the same compilation command. How do I work around this to toggle between the two implementations with only one main.c?
Use the preprocessor and a constant that you can set on the command line:
In your main.c:
#ifdef TREE_IMPL1
#include "TreeImplementation1.h"
#else
#include "TreeImplementation2.h"
#endif
// ...
int main(int argc, char **argv)
{
#ifdef TREE_IMPL1
// code for testing TreeImplementation1
#else
// code for testing TreeImplementation2
#endif
}
When you compile, pass or omit TREE_IMPL1 on the command line, or set it in your IDE:
gcc -DTREE_IMPL1 main.c ...
Do your implementations have the same name? They shouldn't.
If (or when) they don't have the same name, you can just include both headers in main.c and test either one depending on some preprocessor directive.
//main.c
#include "Tree_implementation1.h"
#include "Tree_implementation2.h"
int main()
{
#ifdef TEST_FIRST
testFirstTree(); //declared in Tree_implementation1.h
#else
testSecondTree(); //declared in Tree_implementation2.h
#endif
return 0;
}
Another solution for your problem is using of dynamic interface.
Work the way like that:
#include "Imp_1.h"
#include "Imp_2.h"
typedef void (*TreeFunctionType1)(Tree,param);
typedef void (*TreeFunctionType2)(Tree);
typedef struct ITree
{
TreeFunctionType1 func1;
TreeFunctionType2 func2;
}ITree;
static ITree _Itree={0};
void SetImp(TreeFunctionType1 f1,TreeFunctionType2 f2)
{
tree.func1 = f1;
tree.func2 = f2;
}
/*Use only this functions in your Tests code*/
//{
void Func1(Tree tree,Param param)
{
(*_Itree.func1)(tree,param);
}
void Func2(Tree tree)
{
(*_Itree.func2)(tree);
}
//}
int main(int argc, char const *argv[])
{
SetImp(Imp_1_f1,Imp_1_f2);
TestCode();
SetImp(Imp_2_f1,Imp_2_f2);
TestCode();
return 0;
}

Make a single definition from main.c to be available for a library at compile time

Lets say I have a main.c file
#include "library.h"
#define LIBRARY_VALUE 5
int main(void)
{
somefunction1();
return 0;
}
library.h
void somefunction1(void);
library.c
#include "library.h"
#ifndef LIBRARY_VALUE
#define LIBRARY_VALUE 1
#endif
static unsigned char oneString[LIBRARY_VALUE]; // Also I need to be able
// to use the value to initialize
// static arrays that will be
// modified by somefunction1();
void somefunction1(void)
{
printf("The Library Value is %d\n", LIBRARY_VALUE);
}
What I want to do here, is to be able to compile main.c and having LIBRARY_VALUE‘s value to be used as I defined right after the include in main.c.
How should I use GCC in order to achieve this?
I do need the value to be defined in main.c.
In case I have to change my code, I need a minimum working example code please. So I know clearly how to do this. Thanks.
In C there is no way for different .c files to share a common macro defined in one of the .c files. The tradition is to put it in a .h file, but you say this will not work for you.
You will need a type of "constructor" function that sets up your "static" information at run time. This constructor can be called directly by main.c, or indirectly by having main.c define an extern the library picks up.
I'll throw you some code, but I haven't tried to compile it... I'll leave that as an exercise for the student.
main.c
#include "library.h"
int const library_value = 5;
int main(void)
{
somefunction1();
return 0;
}
library.h
extern int const library_value;
void somefunction1(void);
library.c
#include <assert.h>
#include "library.h"
static unsigned char *oneString;
// destroy any memory from lib_init().
static void lib_clear(void)
{
if ( oneString )
{
free(oneString);
oneString = NULL;
}
}
// initialization - strop the static if the caller is to start it up.
static void lib_init( void )
{
if ( ! oneString ) // (defensive "if" to be sure)
{
assert( library_value > 0 );
oneString = (unsigned char*)malloc( library_value );
atexit( &lib_clear );
}
}
void somefunction1(void)
{
if ( ! oneString ) // if the main() is not calling an the constructor then
lib_init(); // // every method within the library must do so.
printf("The Library Value is %d\n", library_value);
}
The lib_init() and lib_clear() methods could be made externs with a lib_init( int size ) signature to take the size.
Your goal seems to have a single definition referenced multiple places.
There are a limited number of possibilities:
#define in .h
extern defined in main, or somewhere else outside of library.
extern defined in library.
Value passed by caller to library, perhaps an initialization call for the library.
Something defined before #include library.h that is picked up by library.h. I don't like this one.
As alfa says, make it a compile-time definition.
An example of a #define within library.h.
// library.h
#ifndef LIBRARY_VALUE
#define LIBRARY_VALUE 1
void somefunction1(void);
#endif
Or, have main define a value defined by the caller and referenced by the library:
// library.h
extern int const library_value; // caller to define in main
void somefunction1(void); // function for caller
// main.c
int const library_value = 5;
int main(void)
{
somefunction1();
return 0;
}
The one I don't like is:
//main.c
#define LIBRARY_VALUE 5
#include "library.h"
//library.h
#ifdef LIBRARY_VALUE
int const library_value = LIBRARY_VALUE; // executable code in .h files is evil
#endif
Some of the reasons I dont' like this is that it is obscure and unconventional, if two or more callers of library.h define LIBRARY_VALUE you will, or at least should, get obscure link time errors. The same applies if LIBRARY_VALUE is not defined by an #include... library.c itself can not define a default value. No, I'd much rather call an initialization function for the library that accepts the constant.
The problem with the way you seem to want this to work, is that the constant gets used when the library is compiled -- you can't use one value when compiling the library and then compile a program with a different value and expect the library's code to magically change to use the new constant. You have some options when it comes to alternatives, though.
You could move the array into the program rather than the library, and give the library a pointer to it, and its size.
Or you could use a dynamically allocated array in the library, and add an initialization function to do the allocation (using the size provided by the program).
Or, you could ditch the library and just compile its code as part of the program -- then you can use a constant defined for the program as long as its done where the (previously) library code will see it.
Recommendation (assuming you want "myarray" visible outside the library):
// library.h
#ifndef LIBRARY_H
#define LIBRARY_Y
#define ARRAY_SIZE 5
extern unsigned char myarray[ARRAY_SIZE]; // Also I need to be able
// to use the value to initialize
// static arrays that will be
// modified by somefunction1();
void somefunction1(void); // function for caller
#endif
/* LIBRARY_H */
Otherwise, if you just want "somefunction1()" and the array size, then declare another function, "array_size ()":
// library.h
#ifndef LIBRARY_H
#define LIBRARY_Y
#define ARRAY_SIZE 5
int array_size (); // library.c will define "myarray" and it will
// define function array_size as "return ARRAY_SIZE;"
void somefunction1(void); // function for caller
#endif
/* LIBRARY_H */
ALSO:
Please remember that "static" has two meanings:
1) Hides visibility of a variable or function name to file scope (the name is "invisible" outside of the source file)
2) allocates space for the object from static storage (instead of the heap (malloc/new) or stack (local variables)).
If you only want the "static storage" part; then you don't need the keyword "static". Just define your variable outside of a function, and you're set :).
Yet another issue is whether you want to make "ARRAY_SIZE" a compile time variable. If so, you should make sure it gets defined EXACTLY ONCE (when library.c is compiled), and is used IN ONLY ONE PLACE (library.c and library.c only). For example:
// library.c
#include "library.h"
#ifndef ARRAY_SIZE
#error ARRAY_SIZE IS UNDEFINED!
#else
static unsigned char myarray[ARRAY_SIZE];
int array_size ()
{
return ARRAY_SIZE;
}
#endif
...
What you are trying to do is not possible because library.c and main.c are compiled separately. You should compile library.c with "gcc -DLIBRARY_VALUE=5 ..." instead.

Sharing variables across files in C

I have two files:
hudwidgets.c
#include "osd.h"
#include "osdadd.h"
#include <stdio.h>
struct TextSize tsize;
char buff[50];
void hud_draw_lin_compass(int cx, int cy, int tick_maj, int tick_min, int range, int heading)
{
.. important code that uses buff ..
}
hud.c
#include "hudwidgets.h"
#include "hud.h"
#include "osd.h"
#include "osdadd.h"
.. some code ..
void hud_rc_plane_single_frame()
{
fill_mem(0x0000);
if((frame / 50) % 2 == 0)
{
get_next_warning(buff);
}
.. some more code ..
}
The problem I have is that when I try to compile this, the compiler complains of no buff defined, but when I try to define it, the linker complains of two buff variables. Catch-22. To this end, I am asking two questions:
how to fix this, and;
if it is possible to use the same variable thus saving memory because only one variable needs to be allocated (working with a memory constrained microcontroller.)
You need this in the top of hud.c, and any other .c file you use them from:
extern struct TextSize tsize;
extern char buff[50];
The extern keyword tells the compiler that the "actual" variables already exist, in some other unit (file), and the linker will fix it all up for you in the end.
If you're doing this on a large scale in a project, consider how you might encapsulate globals in one place, and create a shared .h file that declares these things as "extern" for all the places that you use them from.
use "extern char buff[50];" in the files where you have not initialized the buff and want to use it. This tells that the declaration is done in other files and you are using it in this file.

Resources