Sharing Dynamically Allocated Arrays Among Functions in a Dynamic-Link Library - c

I have a C shared library (in my case, a DLL) that is used for function calls in a very procedural way. In other words, the main application (.exe) makes separate function calls to this DLL at different times. I would like to share the same array variable among certain functions in the DLL. There is a function that allocates and initializes the array. There is another function that uses the array for some computations. But these functions are called from the main application separately. So I can't pass the array from the initialization function to another in the DLL, because each function is invoked separately (at different times).
I'd like to avoid using a global variable. I could do that, and statically define the array to have a large enough size just to be "safe". But large enough may mean unnecessarily very large. I've seen posts suggesting defining the array in a function, but as a static variable and dynamically allocate it in the initialization function call, but I would still need to have access to the same array in other functions.
What is the best way to keep the code general (i.e., with dynamic memory allocation) while ensuring the same array can be accessed from multiple functions?
UPDATE
A few more details after some discussion.
One possible approach would be to keep a handle to the array in the caller (.exe) and pass it to a DLL function when needed. But, from an interface/API perspective, it wouldn't make sense to keep passing this array, because that would require changing function signatures that aren't meant to be changed. The array should really reside in the DLL and be accessible everywhere. I only need to update its contents when calling the initialization function in the DLL. Then the other DLL functions will make use of it internally to the DLL.

Related

How to persist a function pointer in C?

Suppose that I have a function pointer which can be invoked to do some tasks. How can I store the piece of code, to which the pointer is pointing, to a file on disk so I can later load the file and have the function pointer available again?
Use case: This will be done inside a JIT compiler to prevent the future overhead of JIT-ing in the next run of the same program.
Edit: The answer to "Save and load function pointers to file" are not what I am looking for. That question is dealing with a limited number of functions to which people have suggested using indices. But in my case, the function can be anything with any content.
There is no portable way to do that. Your options are:
Associate pointers with symbolic names of your choosing, e.g. using a global mapping table, and serialize the function name. On deserialization, look up the actual pointer in the mapping.
Serialize real function names, possibly also contained with a mapping. On deserialization, use dlsym (or equivalent on non-Unix platforms, such as GetProcAddress) to get the function pointer.

change the C function contents at run-time

I have a use-case in which the function contents are to be selected conditionally. And that function pointer is passed to other module for later invocation.
void encode_function(int flag)
{
if (flag == 1)
encode1();
if (flag == 2)
encode2();
encode_defaults();
}
Once the encode_function() is populated, I will pass it to other module, where it will be invoked.
I am trying to achieve it in C language, but no success so far. I tried to look at dyncall library but it supports only dynamic parameter changes.
I am looking for something which allows me to change the function contents at run-time.
Some existing question Is there a way to modify the code of a function in a Linux C program at runtime?
You are basically looking for the ability to treat code as data, which is a feature rarely available in compiled imperative static languages like c. The capability of modifying functions at run time is generally categorized as high order functions (you're basically trying to return a function as data somewhere in the code).
If the problem can be solved by several static functions, you can pass in function pointers to different implementations, otherwise I think c does not have the ability to really treat code as data and modify them on the fly.
This question makes attempt to implement high order function in c, but going this far might not be what you want.

return a static structure in a function

C89
gcc (GCC) 4.7.2
Hello,
I am maintaining someones software and I found this function that returns the address of a static structure. This should be ok as the static would indicate that it is a global so the address of the structure will be available until the program terminates.
DRIVER_API(driver_t*) driver_instance_get(void)
{
static struct tag_driver driver = {
/* Elements initialized here */
};
return &driver;
}
Used like this:
driver_t *driver = NULL;
driver = driver_instance_get();
The driver variable is used throughout the program until it terminates.
some questions:
Is it good practice to do like this?
Is there any difference to declaring it static outside the function at file level?
Why not pass it a memory pool into the function and allocate memory to the structure so that the structure is declared on the heap?
Many thanks for any suggestions,
Generally, no. It makes the function non-reentrable. It can be used with restraint in situations when the code author really knows what they are doing.
Declaring it outside would pollute the file-level namespace with the struct object's name. Since direct access to the the object is not needed anywhere else, it makes more sense to declare it inside the function. There's no other difference.
Allocate on the heap? Performance would suffer. Memory fragmentation would occur. And the caller will be burdened with the task of explicitly freeing the memory. Forcing the user to use dynamic memory when it can be avoided is generally not a good practice.
A better idea for a reentrable implementation would be to pass a pointer to the destination struct from the outside. That way the caller has the full freedom of allocating the recipient memory in any way they see fit.
Of course, what you see here can simply be a C implementation of a singleton-like idiom (and most likely it is, judging by the function's name). This means that the function is supposed to return the same pointer every time, i.e. all callers are supposed to see and share the same struct object through the returned pointer. And, possibly, thy might even expect to modify the same object (assuming no concurrency). In that case what you see here is a function-wrapped implementation of a global variable. So, changing anything here in that case would actually defeat the purpose.
As long as you realize that any code that modifies the pointer returned by the function is modifying the same variable as any other code that got the same pointer is referring to, it isn't a huge problem. That 'as long as' can be a fairly important issue, but it works. It usually isn't the best practice — for example, the C functions such as asctime() that return a pointer to a single static variable are not as easy to use as those that put their result into a user-provided variable — especially in threaded code (the function is not reentrant). However, in this context, it looks like you're achieving a Singleton Pattern; you probably only want one copy of 'the driver', so it looks reasonable to me — but we'd need a lot more information about the use cases before pontificating 'this is diabolically wrong'.
There's not really much difference between a function static and a file static variable here. The difference is in the implementation code (a file static variable can be accessed by any code in the file; the function static variable can only be accessed in the one function) and not in the consumer code.
'Memory pool' is not a standard C concept. It would probably be better, in general, to pass in the structure to be initialized by the called function, but it depends on context. As it stands, for the purpose for which it appears to be designed, it is OK.
NB: The code would be better written as:
driver_t *driver = driver_instance_get();
The optimizer will probably optimize the code to that anyway, but there's no point in assigning NULL and then reassigning immediately.

Re-initialize library variables in C program

I am trying to write a program where I have to call some functions through a (shared) library (its source is available). The C code for the library has several global variables, and many functions change the values of these global variables. What I have to do in my program requires that each function call that I make gets to work with a fresh set of variables.
For example, let this function be a part of the library:
int x = 1;
int foo()
{
int a = 0;
//do somethings to 'a'
//...
x++;
return a;
}
Now every time I invoke foo() from my program, the value of x gets update from 1 to 2 then 3 then 4 and so on... I am try to construct a program so that every time foo() is invoked, it sees x = 1.
I am sorry to say that my knowledge of how C/linux treat these variable spaces is insufficient, so this question may seem vague. The above is just a small example; in reality, there are so many variables that is practically impossible to reset their values manually.
What may be the best way to compile that library and/or use it my program so as to refresh the variables?
(On a side note, what I am also trying to do is to parallelize calls to foo(), but because of the shared variables, I cannot do that.)
EDIT:
When working on some web dev projects, I used to encapsulate some code in webservices and then invoke those services from the main program. Does a similar framework exist in C/Linux? Please note that functions are returning data.
You have discovered one of the main reasons that global variables (or global state in general) are a really bad idea.
Since you have access to the source, I would suggest investing some time to refactor the source code.
You can achieve the ability to parallelize calls to foo with the following strategy:
Gather up all of the global variables into a single struct. Call it something like Context.
Change each function that acts on a global variable to take a pointer to a Context, and change the function to update the variables in the Context instead of updating global variables.
Now each thread that wants to use the library can create a new Context and pass that into foo and related functions.
If it's not feasible to make such a change to the source code, you can use more than one CPU core by starting child processes. Each child process has it's own memory space. That option is not nearly as efficient as using multiple threads.
I have no answer in details. But you can try one of the following:
unload and load library
try to clear library's .bss and fill .data section with values from the library (ref dl_iterate_phdr() call).

virtual function == function pointer?

A set of function pointers grouped
into a data structure are often
referred to as a virtual function
table (VFT).
The above statement makes me feel that virtual function == function pointer,is that so?
There is no built-in support for virtual functions in C.
In C++ virtual functions are specified via a v-table. And the entries in a vtable can be implemented as function pointers.
That’s wrong because these are different levels of abstraction.
An analogy may help: saying that virtual functions and function pointers are identical is like saying that wheels and bikes are identical.
While it’s true that function pointers and virtual functions may look much the same “under the hood”, they are different things – both conceptionally (a virtual function is an overriable member method of a class while a function pointer is simply an indirection of a function) and syntactically (calling them is completely different).
They may serve the same purpose, however. In particular, both provide a means of deferring a calling decision (which function to call in this situation?) until runtime when normal call dispatching happens at compile time.
I'd say close, but not quite. A virtual function is still a function, but it's normally called via a pointer, not directly.
Yes, a virtual function table is often implemented under the hood as a table of function pointers. However, there is also other hardware to go along with the table of pointers to make the functions actually "virtual". You have to have a mechanism in place to bind a call to the correct pointer at run-time, etc. I say this because it would be wrong to think that since a virtual function is a function pointer at its most basic level that that makes any function pointer a virtual function.
Actually C++ Supports Virtual Functions , but C Does not supports VF because both are totally different concepts
Virtual function in C++ by definition is a function declared with keyword virtual (immediately or in one of the base classes). That's all.
Now, calls to virtual functions can be resolved statically or dynamically. A dynamically-resolved call is a call that resolved in accordance with dynamic type of the object used in the call. That's all.
Nothing in the above has any references to any "function pointers". However, in a typical implementation in order to implement the proper behavior of dynamic calls, a table with function pointers (pointing to virtual functions) is used. This table is what is known as "VMT", "VFT" or "vtable".
In other words, function pointer is an implementation detail typically used to provide support for dynamic calls to virtual functions.
To illustrate it further, note, for example, that even if some function is virtual, but it is never called dynamically, then there's no need to generate any "pointers" for that function. For this reason, some compilers do not generate VMTs for abstract classes, since even though these classes have virtual functions, these functions are never called dynamically.
I guessed it's from the Understanding Linux Network Internals book -- We're talking about C here, and you've got your parenthesis wrong -- it's virtual (function table), not (virtual function) table :). Virtual functions are a C++ only term.
Which doesn't mean you can't code OOP in ANSI C...

Resources