I have created a small program mirroring my source code. Here main, when in debug mode, calls external library tester functions before it runs the main app. Imagine the constructor function in that library allocates memory and when in debug also tests some static functions. If that library is tested, it runs static tester code. If that library is used, static tester code. the static testers run every time the library function is called.
main.c
// calls test and library
#include <stdio.h>
#include <stdlib.h>
// to test if the lib is there and the function does what it says claims
extern int testExternalLibFunctions(void);
#include "lib.h"
int main(){
testExternalLibFunctions();
printf("main function uses doTheTango\n");
doTheTango();
// do the magic stuff here and
doTheTango();
return 0;
}
test_lib.c
#include <stdio.h>
#include "lib.h"
static int Static_doTheTangoTest();
int testExternalLibFunctions(){
// define DO_THE_TANGO_TEST_SELF_TRUE
Static_doTheTangoTest();
// undefine DO_THE_TANGO_TEST_SELF_TRUE
return 0;
}
int Static_doTheTangoTest(){
printf("external function tester calls doTheTango\n");
doTheTango();
return 0;
}
lib.h
#ifndef DO_THE_TANGO_HEADER
#define DO_THE_TANGO_HEADER
extern int doTheTango();
#endif // DO_THE_TANGO_HEADER
lib.c
#include <stdio.h>
#include <assert.h>
#include "lib.h" //self
// ONLY HERE SHOULD STATIC FUNCTIONS BE TESTED
static int STATIC_TEST();
int doTheTango(){
printf("Dancing is fun - ");
// if defined DO_THE_TANGO_TEST_SELF_TRUE
STATIC_TEST();
// endif
getchar();
return 0;
}
int STATIC_TEST(){
printf("Static test 1, Yet again!");
return 0;
}
It is not the intention to split tester and main function, because the main is calling more testers, etc ... they are inter-dependant!
How can I make the library do the static tests only when first included? Something like in python, where you test
if(__name__ == __main__) -> do the static tests
I'm not sure I understand what you are trying to do. I see from the source code that you say "Static test 1, Yet again!", so I assume you don't want the STATIC_TEST to be called on subsequent calls to doTheTango.
If this is what you want, then do:
int doTheTango(){
static int isTested = 0;
printf("Dancing is fun - ");
if (!isTested) {
isTested = 1;
STATIC_TEST();
}
getchar();
return 0;
}
This is working! and actually also what I was looking for!
// in the global doTheTangoTest you define:
extern int TEST_TANGO_SELF;
doTheTangoTest{
// to set it to 1 if the library is testing itself
TEST_TANGO_SELF = 1;
doTheTango();
// to set it to 0 if testing itself is finished
TEST_TANGO_SELF = 0;
}
and in doTheTango source
// you define again, but not as extern this time, just as int
int TEST_TANGO_SELF;
int doTheTango(){
printf("Dancing is fun - ");
// and use this global variable in a simple if statement
if(TEST_TANGO_SELF){
STATIC_TEST();
}
getchar();
return 0;
}
Related
I have a simple program like:
int velocity=0;
#include "extra.h"
int main()
{
extra();
return 0;
}
where extra.h is:
void extra(){
velocity += 1;
}
yet when I compile this, I get the error:
extra.h:5:5: error: 'velocity' was not declared in this scope
Obviously, my code in extra.h can't "see" the variables in main.c, but why is this? How do I fix this?
You could add the following declaration to extra.h:
extern int velocity;
However, extra() shouldn't be defined in extra.h in the first place. This will cause problems if extra.h is included by multiple .c files in the same binary. The following is what you should have:
extra.h:
void extra();
extra.c:
#include "extra.h"
static int velocity = 0;
void extra() {
velocity += 1;
}
main.c:
#include "extra.h"
int main()
{
extra();
return 0;
}
I have file.h:
extern int global_value;
and file1.c:
#include "file.h"
int global_value = 0;
main()
{
while(1)
global_value++;
}
and file2.c:
#include "file.h"
main()
{
while(1)
printf("%d", global_value);
}
My problem is that the value on the display is always 0.
Where is the problem?
Global variables have a limited scope which does not extend beyond the current executable.
ok, I find it, I use the IPC shared memory and it works correctly
I'm getting started with C programming. I currently have a large file that contains a lot of functions. I would like to move these functions to a separate file so that the code is easier to read. However, I can't seem to figure out how to properly include/compile and can't find an example in any online tutorials that I've found. Here's a simplified example:
#include <stdlib.h>
#include <stdio.h>
void func1(void) {
printf("Function 1!\n");
}
void func2(void) {
printf("Function 2!\n");
}
int main(void) {
func1();
func2();
return 0;
}
How do you move C functions into a separate file? FYI: I'm using gcc.
Update: These answers are very helpful, thank you. Now it seems that my simplified example is not good enough because I realized the reason my program failed to compile is because I'm using a global variable in my functions.
#include <stdlib.h>
#include <stdio.h>
int counter = 0;
void func1(void) {
printf("Function 1!\n");
counter++;
}
int main(void) {
func1();
return 0;
}
Moving these functions to an external file doesn't work because they need to reference this global variable:
#include <stdlib.h>
#include <stdio.h>
#include "functions.c"
int counter = 0;
int main(void) {
func1();
counter = 100;
return 0;
}
How can I get around this issue?
Okay. Here we go.
Your main.c file
#include <stdlib.h>
#include <stdio.h>
#include "functions.h"
int main(void) {
func1();
func2();
return 0;
}
Your functions.h file
void func1(void);
void func2(void);
Your functions.c file
#include "functions.h"
void func1(void) {
printf("Function 1!\n");
}
void func2(void) {
printf("Function 2!\n");
}
Compile it with:
gcc -o main.exe main.c functions.c
The most common way is to place your function prototypes in a header file and your function implementations in a source file. For example:
func1.h
#ifndef MY_FUNC1_H
#define MY_FUNC1_H
#include <stdio.h>
// declares a variable
extern int var1;
// declares a function
void func1(void);
#endif
func1.c
#include "func1.h"
// defines a variable
int var1 = 512;
// defines a function
void func1(void) {
printf("Function 1!\n");
}
func2.h:
#ifndef MY_FUNC2_H
#define MY_FUNC2_H
#include <stdio.h>
void func2(void);
#endif
func2.c:
#include "func1.h" // included in order to use var1
#include "func2.h"
void func2(void) {
printf("Function 2 with var1 == %i\n", var1);
}
main.c:
#include <stdio.h>
#include "func1.h"
#include "func2.h"
int main(void) {
var1 += 512;
func1();
func2();
return 0;
}
You would then compile using the following:
gcc -c -o func1.o func1.c
gcc -c -o func2.o func2.c
gcc -c -o main.o main.c
gcc -o myprog main.o func1.o func2.o
./myprog
I only placed one function in each source/header pair for illustration. You could create just one header which includes the prototypes for all of the source files, or you could create multiple header files for each source file. The key is that any source file which will call the function, needs to include a header file which includes the function's prototype.
As a general rule, you only want a header file included once, this is the purpose of the #ifndef #define #endif macros in the header files.
First you have to learn the difference between a declaration and definition. A declaration tells the compiler that something, like a function, exists. A definition is, for the case of functions, the actual function implementation.
So what you do is move the definition to another file, but add a declaration in the file where the function is to be called. You then build both files together, and the compiler and linker will take care of the rest.
You can do something like this.
/* func1.c */
void func1(void) {
printf("Function 1!\n");
}
/* func2.c */
void func2(void) {
printf("Function 2!\n");
}
/* main.c */
#include "func1.c"
#include "func2.c"
int main ( void )
{
func1();
func2();
return 0;
}
I have been reading the on-line book Basics of libuv and trying to rewrite them to work with both a static link and a dynamic link to the libuv library. I rewrote the watchers example (code below), but I had to "rename" the functions I retrieved from libuv.dylib to make it work, which means I had to write an entirely separate code path for the dynamic linking case. Can I somehow keep the same function names?
I want my code to look like this.
#include <stdio.h>
#include <uv.h>
#ifdef DYNAMIC
#include <dlfcn.h>
#endif
int64_t counter = 0;
void wait_for_a_while(uv_idle_t *handle, int status) {
counter++;
if (counter >= 10e6)
uv_idle_stop(handle); // This function pointer must be a global variable
}
int main(int argc, char **argv) {
uv_idle_t idler;
// Initialize code needed for dynamically-linked library
#ifdef DYNAMIC
void *lib_handle = dlopen("libuv.dylib", RTLD_LOCAL|RTLD_LAZY);
// Set up pointers to functions defined in libuv.dyld ...
#endif
uv_idle_init(uv_default_loop(), &idler);
uv_idle_start(&idler, wait_for_a_while);
printf("Idling...\n");
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
// Clean up dynamically linked code
#ifdef DYNAMIC
dlclose(lib_handle);
#endif
return 0;
}
Currently, it looks like this.
#include <stdio.h>
#include <uv.h>
#ifdef DYNAMIC
#include <dlfcn.h>
// Currently, I need to define function pointers with different names
// than the functions they call
uv_loop_t* (*uln)(void);
int (*ur)(uv_loop_t*, uv_run_mode);
uv_loop_t* (*udl)(void);
int (*uii)(uv_loop_t*, uv_idle_t*);
int (*uist)(uv_idle_t*, uv_idle_cb);
int (*uisp)(uv_idle_t*);
#endif
int64_t counter = 0;
void wait_for_a_while(uv_idle_t *handle, int status) {
counter++;
if (counter >= 10e6)
#ifdef DYNAMIC
uisp(handle);
#else
uv_idle_stop(handle); // This should be the only line remaining
#endif
}
int main(int argc, char **argv) {
uv_idle_t idler;
// Code path for dynamic linking case
#ifdef DYNAMIC
void *lib_handle = dlopen("libuv.dylib", RTLD_LOCAL|RTLD_LAZY);
// Retrieve symbol names from libuv.dylib
*(void **)(&uln) = dlsym(lib_handle, "uv_loop_new");
*(void **)(&ur) = dlsym(lib_handle, "uv_run");
*(void **)(&udl) = dlsym(lib_handle, "uv_default_loop");
*(void **)(&uii) = dlsym(lib_handle, "uv_idle_init");
*(void **)(&uist) = dlsym(lib_handle, "uv_idle_start");
*(void **)(&uisp) = dlsym(lib_handle, "uv_idle_stop");
uii(udl(), &idler);
uist(&idler, wait_for_a_while);
printf("Idling...\n");
ur(udl(), UV_RUN_DEFAULT);
dlclose(lib_handle);
// Code for static linking case
#else
uv_idle_init(uv_default_loop(), &idler);
uv_idle_start(&idler, wait_for_a_while);
printf("Idling...\n");
uv_run(uv_default_loop(), UV_RUN_DEFAULT);
#endif
return 0;
}
Change:
#include <uv.h>
#ifdef DYNAMIC
#include <dlfcn.h>
/*...*/
into:
#ifndef DYNAMIC
#include <uv.h>
#else
#include <dlfcn.h>
/*...*/
Now, you can name your function pointer variables the same as the interfaces you want to call them as.
However, it is unclear why you need to do this at all. Normally, you just link your application with the dynamic library. You would only need to do what you are doing if you are experimentally changing the implementation of the dynamic library (treating it like a plugin).
In a comment, you mention that you need the definitions of structures in <uv.h>. Then to make my original proposal work, you would need to redefine those structures in the case of DYNAMIC, since you would not be using the header file. But, if the uv library ever changes, you would lose those changes and be forced to update your DYNAMIC version to match, which is an undesirable situation.
Another work around is to follow your original approach of defining different function pointer names, but then define macros to map the original function names to the function pointer names.
#include <uv.h>
#ifdef DYNAMIC
#include <dlfcn.h>
uv_loop_t* (*uln)(void);
int (*ur)(uv_loop_t*, uv_run_mode);
//...
#define uv_loop_new uln
#defin uv_run ur
//...
#endif
So I have this very simple program but I can't seem to get rid of a simple error.
I have a Header file with this
#ifndef FUNCTIONLOOKUP_H_INCLUDED
#define FUNCTIONLOOKUP_H_INCLUDED
enum functions
{
foo,
bar
};
//predefined function list
int lookUpFunction(enum functions);
#endif // FUNCTIONLOOKUP_H_INCLUDED
And in the src file i have the definition of lookUpFunction
Now when I call the lookUpFunction() from my main where I included the header file it gives me a undefined reference to it. The other awnsered questions where of no help.
#include <stdio.h>
#include <stdlib.h>
#include "FunctionLookUp.h"
int main()
{
lookUpFunction(foo); <---
return 0;
}
Function implementation
#include <stdio.h>
#include "FunctionLookUp.h"
typedef void (*FunctionCallback)(int);
FunctionCallback functionList[] = {&foo, &bar};
void foo(int i)
{
printf("foo: %d", i);
}
void bar(int i)
{
printf("bar: %d", i);
}
int lookUpFunction(enum functions)
{
int test = 2;
//check if function ID is valid
if( functions >= sizeof(functionList))
{
printf("Invalid function id"); // error handling
return 0;
}
//call function
functionList[functions](test);
return 1;
}
I can't seem to figure out where this error comes from.
You must have some file similar to:
/* FunctionLookUp.c */
#include "FunctionLookUp.h"
int lookUpFunction(enum functions)
{
/* code ... */
return x;
}
somewhere in order to solve your problem
You never show code that implements the function.
So it's most likely that what you're seeing is a linker error, the call itself is fine but the linker cannot find the code to call, so it throws an error.
Just declaring a function can't magically make it appear from somewhere, you must write the actual function too.