C- Binding static declared functions

Functions and variables declared static have an internal relationship, and they have the scope of the file, and they are not visible to functions in other files.

Suppose I declare a function like this: -

static int foo(int i); 

in one file named file1.c Can I access this function from another file2.c file using pointers to use.

I am looking at a book that says it can be done, but I don’t know how it is possible.

And these are the exact lines: -

Since it has an internal connection, foo cannot be called directly from outside the file in which it is defined. (Declaring foo for static does not completely prevent it from being called in another file; indirect calling through a function pointer is still possible).

+7
c scope static
source share
5 answers

Perhaps you are looking for this?

 // file1.h extern void (*fptr)(void); // file1.c static void foo(void) { printf("Hello world!\n"); } void (*fptr)(void) = &foo; //or void (*fptr)(void) = foo; // file2.c #include "file1.h" fptr(); 

Here foo is static, but its address is referenced via a non static global variable. And it is quite possible.

+4
source share

A function cannot be called by name in any other file, since it is static in another file, but you can do this with a pointer to it.

extern int (*pf)(int);

You need to assign foo this pointer, and then you can access it.

+2
source share

H2CO3 gives the correct answer, in another way:

 /* ah */ typedef int (*fptr)(int); fptr call_foo(void); 

 /* ac */ #include "ah" static int foo(int i) { return i * 2; } fptr call_foo(void) { return foo; } 

 /* main.c */ #include <stdio.h> #include "ah" int main(void) { fptr fn = call_foo(); printf("%d\n", fn(2)); return 0; } 
+1
source share

Another way to do this, which, in my opinion, can be used is to make your static function a callback.

 //------------------------------ // file react.c #include "event.h" static void react_on_event_A(void) { // do something if event_A occurs. } void react_init(void) { event_setup(EVENT_A, react_on_event_A); } 

Here you configure the react_on_event_A function as a callback that can call the event driver, but blocking anyone else from calling the function by its identifier. Are you really telling someone else to save this feature.

An event driver might look like this:

 //------------------------------ // file event.h typedef enum { EVENT_A, } event_t; void event_setup(event_t event, void (*callback)(void)); void event_check_and_run(void); //------------------------------ // file event.c static void (*event_A_callback)(void); void event_setup(event_t event, void (*callback)(void)) { if (event == EVENT_A) { event_A_callback = callback; } } // Scheduled periodically, or reacting on interrupt. void event_check_and_run(void) { if (occured(EVENT_A) && (event_A_callback != NULL)) { event_A_callback(); } } 

The advantage of this is that the react module controls which other modules ( event in this case) have access to their own static function.

With other alternatives (creating a static function or not, or publishing a pointer in a header file), you provide access to neither anyone, nor everyone.

+1
source share

In short: yes, you can access static methods with pointers.

To understand this, it is best to better understand what is happening under the hood of the compiler.

For clarity, the compiled program is written to machine code. There is additional information in the compiled program for the “program loader”, but the program itself is just instructions that must be executed by the processor.

When you call the "foo ()" function in C, the C compiler translates this into the processor operation "CALL". The CALL operation is performed in code at the address foo (literally, the memory address or "offset"). Note that since this is a memory address, the name ("foo") is not used. Also note that the linker does not need to know about "foo" for this to work.

When you call the "bar ()" function in C, and the function is in another compilation unit (another C file), the compiler has a small problem, because it does not know where in the program (where in memory) the function should call. That is, he does not know what address to write after the CALL operation. When this happens, it writes code that leaves room for the address, but leaves a note for the linker. The note says the linker "put the bar address here." Therefore, the linker corrects the written program using the memory address. To allow the linker to do this; the compiler writes a table containing each function name and corresponding address in the code.

So what does static do? It just tells the compiler not to write the name and address for the function in the table passed to the linker. A function still exists in the code as a function, but the linker does not know where it is. Any code in one compilation unit will know where the function is located. Thus, any function inside one compilation unit can pass the address of the function as a pointer outside the compilation unit.

The c code for using the function pointer looks something like this:

file1.h

 typedef void (* VoidFunctionPointer)(); extern VoidFunctionPointer somethingInteresting; bar(); 

file1.c

 #include "ah" VoidFunctionPointer somethingInteresting; static void foo() { // do something interesting; } void bar() { // we know what foo is because we're in the same compilation unit somethingInteresting = foo; } 

file2.c

 #include "ah" int main(int argC, char ** argV) { bar(); // we can call somethingInteresting as if it is a function no matter // wether it declared static in code or not // this can be foo, just as long as we don't have to use the name "foo" somethingInteresting(); } 

In this code, file2 actually runs a static function from file1. The key is that file2 never needs the name of this function, so the static effect does not affect function pointers.

I can recommend reading Microsoft's description of the PE format (.EXE and .DLL) [here]:

http://msdn.microsoft.com/en-us/library/ms809762.aspx

0
source share

All Articles