Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

C++ wrapper for C library

Recently I found a C library that I want to use in my C++ project. This code is configured with global variables and writes it's output to memory pointed by static pointers. When I execute my project I would like 2 instances of the C program to run: one with configuration A and one with configuration B. I can't afford to run my program twice, so I think there are 2 options:

  • Make a C++ wrapper: The problem here is that the wrapper-class should contain all global/static variables the C library has. Since the functions in the C library use those variables I will have to create very big argument-lists for those functions.
  • Copy-paste the C library: Here I'll have to adapt the name of every function and every variable inside the C library.

Which one is the fastest solution? Are there other possibilities to run 2 instances of the same C source?

Thanks,

Max

like image 510
Maximilien Avatar asked Apr 22 '10 12:04

Maximilien


People also ask

What is C wrapper?

The C Wrapper provides access to RPC-based components from C applications and enables users to develop both clients and server. This section introduces the various possibilities for RPC-based client applications written in C. Using the C Wrapper in Single-threaded Environments (UNIX, Windows)

Can C code use C++ library?

Oracle Developer Studio C and C++ use the same C runtime libraries, as noted in the section about compatible compilers. Using Oracle Developer Studio compilers, you can therefore use Standard I/O functions freely in both C and C++ code in the same program.

What is wrapper library C++?

A wrapper consists of three separate code libraries; these are the top-level library and the fenced and unfenced libraries. The shared library for the top-level library is provided as part of the wrapper development kit. The remaining two libraries must be built from your wrapper code.

Why is C plus plus standard library required?

The C++ Standard Library provides several generic containers, functions to use and manipulate these containers, function objects, generic strings and streams (including interactive and file I/O), support for some language features, and functions for everyday tasks such as finding the square root of a number.


3 Answers

C++ -Wrapper
You get away easier by pasting "the entire library" - only slightly modfied - into a class.

// C
static char resultBuffer[42];
void ToResult(int x) { ... }
char const * GetResult() { return resultBuffer; }

becomes

// C++
class CMyImportantCLib
{
  private:
    char resultBuffer[42];
    void ToResult(int x) { ... } // likely, no code changes at all
    char const * GetResult() { return resultBuffer; }
} ;

There are mostly declarative changes (such as "killing" static and extern declarations). You would need to hunt down static variables inside the methods, though, and turn them into members as well

Separate Namespaces
That is an ugly solution, but might be enough for you:

// impMyLib.h
namespace A 
{
  #include "c-lib.h"
}
namespace B
{
  #include "c-lib.h"
}

// impMyLib.cpp
namespace A 
{
  #include "c-lib.c"
}
namespace B
{
  #include "c-lib.c"
}

If you are lucky, the optimizer/linker succeeds in folding the identical code. However, types in A:: and B:: are unrelated.

like image 120
peterchen Avatar answered Sep 28 '22 01:09

peterchen


If you can't afford to run it twice, how about 3 times? You could conceivably write a tiny front-end process that launches two separate instances of your C program. From the usage perspective it would still look like a single .exe that you run only one time but behind the scenes you'd have a parent process with two children. I have no idea if that approach would suit your actual needs but it'd almost certainly be faster than either of your other two options.

like image 45
Rakis Avatar answered Sep 28 '22 00:09

Rakis


IIUC, what you have is, basically, this:

extern int a;
extern int b;

void f();
void g(); 

where a and b modify the behavior of f() and g(). Is that correct?

If you have this and you want to wrap this in C++, then what you could do is this:

class the_library {
public:
  the_library(int a, int b) : a_(a), b_(b) {}

  void f() {a=a_; b=b_; ::f();}
  void g() {a=a_; b=b_; ::g();}
private:
  int a_;
  int b_;

};

Depending on what you have instead of a and b, this might not be terribly efficient.

Of course, as Raki said in the comments, since this is using global variables, it's not at all thread safe.

like image 29
sbi Avatar answered Sep 28 '22 02:09

sbi