I need to generate a static library MyLib.lib that contains unimplemented functions.
Inside the project, I called the unimplemented function as shown below:
/* Inside MyLib.c */
#include "MyLib.h"
void foo(void)
{
func(); // To be implemented by the user.
}
And In the header file MyLib.h, I included a header file
#include "user.h" // contains user_imlplementation_of_func()
...
#define func() user_imlplementation_of_func()
To make things simple, let's just give an example of the user.c:
void user_imlplementation_of_func(void)
{
printf("OK");
}
I would like to know is it possible to do this call? Otherwise, Is there any other solution to use unimplemented functions inside a static library and let the user define them after compressing the project from a source code to a .lib file
You need to declare the unimplemented function as extern in the header of your library. This tells the compiler, that the function will be defined somewhere else.
Example:
MyLib.h
void foo();
extern void func();
MyLib.c
#include "MyLib.h"
void foo(void)
{
func();
}
main.c
#include <stdio.h>
#include "MyLib.h"
void func()
{
printf("Hello, world!\n");
}
int main()
{
foo();
}
Example build:
cc -o MyLib.o -c MyLib.c
cc -o out main.c MyLib.o
Output:
$ ./out
Hello, world!
However, for more readability I suggest you to pass your project functions as pointers to your library functions. This is commonly known as callback.
Example:
/* MyLib.c */
#include "MyLib.h"
void foo(void (*func)(void))
{
func();
}
Now you can call the foo function in your project with:
foo(&user_imlplementation_of_func);
Edit:
As stated in the comments by the user theSealion a third solution is the usage of weak symbols. The wikipedia articel "Weak symbol" provides a good explanation with examples.
You can do some else - function pointer:
//youLib.c
extern void (*func)(void) = NULL;
extern void foo()
{
if (func != NULL) {
func();
}
}
//main.c
static void user_imlplementation_of_func(void)
{
printf("Hello\n");
}
func = &user_imlplementation_of_func;
foo(); //Will printf "Hello"
Related
consider the following code, which causes a weird behavior:
foo.h
#ifndef FOO_H
#define FOO_H
void foo();
#endif
foo.c
#include <stdio.h>
// NOTICE - foo.h is not included!
void foo()
{
printf("foo!\n");
}
main.c
#include "foo.h"
int main()
{
foo();
return 0;
}
running this code I get in the console: foo!
what bugs me here is that I expected that main.c would not be familiar with the implementation of foo(), since foo.h is not included in foo.c, and hence foo() should be an inner function in foo.c. It happened to me both when I ran it in VS2010 and when I compiled an exe using gcc (on windows).
can someone explain this phenomenon? I thought about it and I have no idea why it happens. thanks.
The header file is declaring the function, so when compiling main.c the compiler knows the function signature to validate against. When compiling foo.c, it doesn't need to be declared, as it is the declaration of the function. It is up to the linker to see if there are any unresolved symbols, which there aren't in this case, so all is good, and also why you're seeing this work.
What will happen if there was another function(test.c) included in the above question.
foo.h
#ifndef FOO_H
#define FOO_H
void foo();
#endif
foo.c
#include <stdio.h>
// NOTICE - foo.h is not included!
void foo()
{
printf("foo!\n");
}
test.c
#include <stdio.h>
void foo()
{
printf("foo!\n");
}
main.c
#include "foo.h"
int main()
{
foo();
return 0;
}
I have three files as such:
module.c:
void bar() {
foo();
}
module.h: (i didn't put the include guard for simplicity)
void bar();
main.c
void foo() {
//some code
}
int main() {
bar();
}
when compiling main.c and module.c, module.c returns an error saying foo() is not defined. How can i fix this up?
Basically, i wanted to take my actual main file, which was pretty large, and split up parts of it to other files for readability, but those functions call other functions found in main
It's tricky because of the directions your dependencies are going.
I can split your code into three compilation units: main.c, module.c, and foo.c
If you do this, you don't have any foo code in main, main only calls bar, and bar includes foo, which is defined in foo.
main.c
#include "module.h"
int main() {
bar();
}
module.c
#include "foo.h"
void bar() {
foo();
}
foo.c
void foo() {
}
Best of all is that you don't need to declare foo outside of foo.h, or bar outside of module.h.
I guess module.h could also define void foo(); thus module.c would implement foo too. On the other hand, if bar depends indirectly on foo, then maybe module.c should include another_module.h implemented by another_module.c.
Put prototype definitions for all your functions into module.h:
int main(int argc,char **argv);
void foo(void);
void bar(void);
int fludger(int abc,char *str);
You get the side benefit that in addition to putting any function in any .c file you wish, you no longer need to order the functions within a given .c file, based upon what calls what [e.g. before if foo called bar, bar would have to be defined above foo]
From this article Unit testing with mock objects in C:
This is done by using the --wrap linker option which takes the name of the wrapped function as an argument. If the test was compiled using gcc, the invocation might look like:
$ gcc -g -Wl,--wrap=chef_cook waiter_test.c chef.c
How can I do this when compiling a C project in visual studio?
The --wrap in ld can be emulated by the /ALTERNATENAME option in MSVC Linker.
We start from two compilation units, say foo.o compiled from foo.c, whose external functions are declared in foo.h, and main.o from main.c.
(If foo has been compiled as a library, things won't change much.)
// foo.h
int foo();
// foo.c
int foo() {
return 0;
}
// main.c
#include <stdio.h>
#include "foo.h"
int main() {
int x = foo();
printf("%s\n", x ? "wrapped" : "original");
}
The return value of int foo() is 0, so the snippet of code above will output "original".
Now we override the actual implementation by an alias: The #include "foo.h" in main.c is replaced by
#define foo real_foo
#include "foo.h"
#undef foo
#pragma comment(linker, "/alternatename:real_foo=foo")
Let me explain what happens here:
by #define foo real_foo, the function declaration in foo.h is modified as int real_foo().
However, the symbol in foo.o is still named after int foo(), instead of the alias int real_foo(). That's why we need the /alternatename linker switch.
"/alternatename:real_foo=foo" tells the linker that, if you cannot find the symbol called real_foo, try foo again before throwing an error.
Apparently there is no definition of int real_foo(). MSVC Linker will search for int foo() and link it instead at each occurrence of int real_foo().
As the previous implementation has been aliased, now we redirect int foo() to our new implementation by a macro:
int wrap_foo() {
return real_foo() + 1;
}
#define foo wrap_foo
And we are done here. At last the main.cpp looks like:
#include <stdio.h>
#define foo real_foo
#include "foo.h"
#undef foo
#pragma comment(linker, "/alternatename:real_foo=foo")
int wrap_foo() {
return real_foo() + 1;
}
#define foo wrap_foo
int main() {
int x = foo();
printf("%s\n", x ? "wrapped" : "original");
}
Built in MSVC, it will output "wrapped".
In one interview I was asked, if in one file A, some static function is defined and in file B you want to use this static function -- how you will use it?
My answers were:
declaring in .h file
But if we declare that in a header file, other files which will include this also have access to this static function.
wrapper concept: Declaring a new function newfun in file A, which will call static function and calling this newfun in file B.
But he was not satisfied with these answers.
Can you please provide me some better solution to violate static.
Perhaps they wanted to hear about function pointers?
You can create a pointer to the function, and call it using that pointer.
One possible scenario where this is reasonable is if you have a callback function that you don't want to be callable by everyone, and you give the pointer as an argument to some register_callback function.
Callback functions were used extensively, for example to let the user of a GUI API provide code for what should happen when a button is pressed. Nowadays, with object-oriented languages, it is more common to subclass a class and define or override methods, such as the Android View class and the method OnClickListener, but C# delegates are very similar to C function pointers.
To illustrate the principle, here is the source code (the file "B" in the original question) for some sort of library, where the main component is the do_stuff function:
#include <stdio.h>
#include "some_library.h"
void (*stored_callback)(void) = NULL;
void register_callback(void (*callback)(void)) {
stored_callback = callback;
}
void do_stuff(void) {
printf("Doing stuff...\n");
printf("Calling callback...\n");
if (stored_callback != NULL)
stored_callback();
}
This header, some_library.h, file shows the API of that library:
extern void register_callback(void (*callback)(void));
extern void do_stuff(void);
And here is how the library is used (the file "A" in the question):
#include <stdio.h>
#include "some_library.h"
static void my_callback(void) {
printf("Inside the callback!\n");
}
int main(void) {
register_callback(my_callback);
do_stuff();
return 0;
}
My interview answer would be "You can't."
(Because the question says "in file B you want to use this static function" and it didn't say you are allowed to modify file A.)
I'm assuming you don't have access to the source of the static function or else you could just remove the static keyword or expose the function via an exported wrapper or global function pointer.
You can still use the static function if you use objcopy to manually change the visibility on the symbol in the object file / library.
Suppose this is the (unaccessible) static function:
//static.c
#include <stdio.h>
static void fun(){
puts("Hello world");
}
Suppose you only have static.o, obtainable with gcc -c static.c.
Now, let's assume you want to link static.o with main.o made from
//main.c
void fun();
void main(){
fun();
};
To be able to link it, you need to turn
$ nm static.o
0000000000000000 t fun
U puts
into
0000000000000000 T fun
U puts
You can do that with:
objcopy --globalize-symbol=fun static.o global.o
Now you can link with global.o instead of static.o.
$ gcc main.o global.o && ./a.out
Hello world
filea.c
#include <stdio.h>
#include "filea.h"
static void hidden(void) { printf("inside hidden function.\n"); }
fxptr unhide(void) { return hidden; }
filea.h
#ifndef FILEA_INCLUDED
#define FILEA_INCLUDED
typedef void(*fxptr)(void);
fxptr unhide(void);
#endif
fileb.c
#include "filea.h"
int main(void) {
unhide()();
return 0;
}
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;
}