Jump to content
  • Advertisement
Sign in to follow this  

Turn a non reentrant C library into a library supporting several instances of itself

This topic is 2081 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

If you intended to correct an error in the post then please contact us.

Recommended Posts



I am wondering how to handle following problem:


I have a C-language library that performs calculations on a mesh, but cannot be called several times (i.e. is not reentrant). I have the source code, and I am wondering how to "wrap" that library so as to be able to instanciate it several times.


I see two options:


1. Write a wrapper in C++. The problem with this approach is that I would have to heavily modify the C library. Knowing that the C library itself will evolve independently, I would have to constantly adapt my wrapper.


2. Not sure if this is possible, but somehow load the library into memory several time. E.g., if that library is compiled as a shared library, my application could dynamically load and use its exported functions. Is there a way or mode that allows to load a same shared library into several different memory locations?


Would there be another option?


Thanks for any insight!


Share this post

Link to post
Share on other sites

The best way is to fix the library so that each function takes some kind of 'context' structure, in to which all the global state is moved. Multiple context structures would allow multiple clients in the same process.


Loading a library twice (at distinct locations in virtual memory) may be possible, but it will be highly platform dependent. What platform(s) do you care about?


It's possible to write a non-intrusive wrapper, as long as you have a true static library (not a stub) and are willing to find all global state. In this case you will have to:

  1. Create a context structure with one member for each piece of global state. 
  2. Create init_context(context *ctx) that initializes a context in the same way that the global state is initialized.
  3. Create get_current_context(context *ctx) and set_current_context(const context *ctx) functions that get and set the current global state
  4. Add a global mutex if you want to use this in a multithreaded environment.
  5. Now wrap each function, f, as follows:

return_type wrapped_f(context *ctx, type1 arg1, type2 arg2, type3 arg3, etc)
    context old_ctx;
    return_type ret = f(arg1, arg2, arg3, etc);
    return ret;


An RAII-style class could automate the locking and context swapping. I admit it's ugly and you'll still have to take care to look for new global state to add to the context structure whenever the underlying library is changed, but it's probably all you can do without modifying the library.

Share this post

Link to post
Share on other sites
Not being reentrant means you can't call it recursively or from multiple threads simultaneously. Do you need to do that? You can get around having to use recursion by batching up a list of meshes to operate on (e.g. do a pass and enumerate all child meshes into a list, then do all the operations on the list one after the other). Rewriting it in C++ wont magically make it safe for reentrancy.

Share this post

Link to post
Share on other sites

Thanks edd and Paradigm Shifter,


The C code has to run on Windows, Mac OSX and Linux. I guess that makes it a bit more complicated for the solution where the library is loaded several times into memory.

I will go with your solution edd, even if a bit troublesome (since I have to touch the original code quite deeply).


Thanks at lot!!

Share this post

Link to post
Share on other sites
Sign in to follow this  

  • Advertisement

Important Information

By using GameDev.net, you agree to our community Guidelines, Terms of Use, and Privacy Policy.

We are the game development community.

Whether you are an indie, hobbyist, AAA developer, or just trying to learn, GameDev.net is the place for you to learn, share, and connect with the games industry. Learn more About Us or sign up!

Sign me up!