Jump to content

  • Log In with Google      Sign In   
  • Create Account

FREE SOFTWARE GIVEAWAY

We have 4 x Pro Licences (valued at $59 each) for 2d modular animation software Spriter to give away in this Thursday's GDNet Direct email newsletter.


Read more in this forum topic or make sure you're signed up (from the right-hand sidebar on the homepage) and read Thursday's newsletter to get in the running!


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


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
3 replies to this topic

#1 floatingwoods   Members   -  Reputation: 292

Like
0Likes
Like

Posted 03 February 2013 - 06:10 AM

Hello,

 

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!

 



Sponsor:

#2 e‍dd   Members   -  Reputation: 2105

Like
3Likes
Like

Posted 03 February 2013 - 06:54 AM

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)
{
    g_mutex.lock();
    context old_ctx;
    get_current_context(&old_ctx);
    set_current_context(ctx);
 
    return_type ret = f(arg1, arg2, arg3, etc);
 
    get_current_context(ctx);
    set_current_context(&old_ctx);
    g_mutex.unlock();
 
    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.



#3 Paradigm Shifter   Crossbones+   -  Reputation: 5438

Like
1Likes
Like

Posted 03 February 2013 - 06:55 AM

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.
"Most people think, great God will come from the sky, take away everything, and make everybody feel high" - Bob Marley

#4 floatingwoods   Members   -  Reputation: 292

Like
0Likes
Like

Posted 04 February 2013 - 03:19 AM

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!!






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS