Elegantly call C++ from C - c++

We develop some project in plain C (C99). But, we have one library as source codes (math library) in C++. We need this library so I would like to ask, what is the most elegant way to integrate this source codes?
Ratio between sizes of C and C++ is 20:1 so moving to C++ is not the option. Should we use static library? DLL? (It's all on Windows).

EDIT: Based on discussion in the comment, I should point out that separating things into a C-compatible struct duck and a derived class Duck is probably unnecessary. You can probably safely shovel the implementation into struct duck and eliminate class Duck, thus obviating real(…). But I don't know C++ well enough (in particular, the way it interacts with the C universe) to offer a definitive answer on this.
There is no reason you can't simply link all your C and C++ code together into a single binary.
Interfacing to the C++ code requires that you wrap the C++ API in a C API. You can do this by declaring a bunch of functions inside extern "C" { ... } when compiling the C++ code, and without the extern declaration when compiling the C client code. E.g.:
#ifdef __cplusplus
extern "C" {
#endif
typedef struct duck duck;
duck* new_duck(int feet);
void delete_duck(duck* d);
void duck_quack(duck* d, float volume);
#ifdef __cplusplus
}
#endif
You can define the duck struct in your C++ source, and even inherit the real Duck class from it:
struct duck { };
class Duck : public duck {
public:
Duck(int feet);
~Duck();
void quack(float volume);
};
inline Duck* real(duck* d) { return static_cast<Duck*>(d); }
duck* new_duck(int feet) { return new Duck(feet); }
void delete_duck(duck* d) { delete real(d); }
void duck_quack(duck* d, float volume) { real(d)->quack(volume); }

The only reason to want to inherit from the duck struct would be to expose some to its attributes in the C API, which is generally considered bad style anyway. Without inheritance, your C header would look like this:
struct Duck;
struct Duck* new_Duck(int feet);
void delete_Duck(struct Duck* d);
void Duck_quack(struct Duck* d, float volume);
And this would be the corresponding implementation, with no need for type casts:
extern "C" {
#include "Duck.h"
}
class Duck {
public:
Duck(int feet) : {}
~Duck() {}
void quack(float volume) {}
};
struct Duck* new_Duck(int feet) { return new Duck(feet); }
void delete_Duck(struct Duck* d) { delete d; }
void Duck_quack(struct Duck* d, float volume) { d->quack(volume); }
In the same way, a C API can be created for a C++ interface (pure virtual class) and its implementations. In that case, only the constructor need to be based on the concrete implementation (e.g. new_RubberDuck(2)). The destructor and all other functions will automatically operate on the correct implementation, same as in C++.

A C++ math library may well be implemented in the for of utility classes (static members only). In this case, a much simpler approach could be taken:
class FPMath {
public:
static double add(double, double);
static double sub(double, double);
static double mul(double, double);
static double div(double, double);
};
The header for the C interface would then be:
double FPMath_add(double, double);
double FPMath_sub(double, double);
double FPMath_mul(double, double);
double FPMath_div(double, double);
And the corresponding implementation might be:
double FPMath_add(double a, double b) { return FPMath::add(a, b); }
double FPMath_sub(double a, double b) { return FPMath::sub(a, b); }
double FPMath_mul(double a, double b) { return FPMath::mul(a, b); }
double FPMath_div(double a, double b) { return FPMath::div(a, b); }
But maybe this is stating the obvious....

There is a way to create a "hack" that allows you to call member functions of some objects directly.
The first thing you have to do is to create an extern "C" factory function, which returns a pointer (as void*) to the object.
The second thing you need is the mangled name of the member function.
Then you can call the function using the mangled name, and passing the pointer returned from the factory function as the first argument.
Caveats:
Will of course not work calling member function that wants other objects, or references, or other C++ stuff, or functions returning objects or types not compatible with C types
Will not work on virtual member functions, and probably not on objects with virtual functions in them even if it's not a virtual function being called
The mangled name have to be a valid C symbol
Any many many more...
This is not something I recommend, quite the opposite in fact. I strongly advise against doing something like outlined in this answer. It's unsupported and probably undefined behavior and may break in weird and unpredictable ways.

Related

Write C wrapper for C++ libraries?

C++11 has sleep_for. But C standard doesn't have the equivalent.
I think I can write a wrapper to call such C++ functions from C.
And there are useful libraries like Boost Filesystem and Asio. These are more complicated but I can also write the wrapper.
Could it be reinventing the wheel? Could it be a bad idea?
An issue with this is, if you want to write C wrappers which call Boost functions, what do you do if an exception is thrown? You basically have to swallow it in the caller before it reaches C, but its a bit awkward to properly report it to C then and there are quite a few types of exceptions.
Usually people use C instead of C++ when they specifically want the extra portability or cannot provide all the C++ dependencies for some reason. If you want to write a C program that uses boost::filesystem, why not just compile it as C++? You will have a lot less exception handling boiler plate code to write, and less can go wrong.
zeroMQ does it that way. The library is written in C++, but the library API is a C interface. In principle, you hide classes in memory blocks of the object size and pass void* around. For a few simple function, e.g. sleep_for, you can just create a wrapper function. In your header, declare
extern "C" {void sleep_for(int duration);}
In your cpp-file, implement this in terms of std::this_thread::sleep_for.
sleep_for(int duration) {std::this_thread::sleep_for( std::chrono::milliseconds(duration);}
For classes, you need C function to create a new object, destruct it and of course to call member functions. For a class A, this could look as follows:
C header file "A_C_API.h":
extern "C" {
enum {SIZE_OF_A = 4};
typedef char[SIZE_OF_A] a_class;
a_class initA(void* a, int x);
void destructA(void* a);
int callGet(void *a);
}
C++ source file:
class A {
public:
A(int i): x{i} {}
int get() const {return x;}
private:
int x;
};
static_assert( SIZE_OF_A == sizeof(A), "size mismatch!");
void initA(void* a, int x) {
new (a) A(x);
}
void destructA(void* a) {
static_cast<A*>(a)->~A();
}
int callGet(void *a) {
return static_cast<A*>(a)->get();
}
In your C application, you can then
#include "A_C_API.h"
int main(int argc, char* argv[]) {
a_class obj;
initA(&obj);
printf("%d", callGet(&obj) );
destructA( &obj );
return 0;
}
You will have to catch exceptions and convert them to some C error handling. You will also have to handle alignment issues on some platforms, especially SPARK platforms. I have omitted this for simplicity, but you can take a look at the zeromq header how to do this.

Returning structs by value across DLL-exported class' method - is it safe?

I'm trying to use a public class method to return some data via structs. The structs have simple c'tors and stateless methods, and some even contain other structs (no C++/STL types though). The class and structs will be exported to DLL.
The entire definition for the structs are contained in headers with the appropriate dllexport or dllimport modifiers because they are meant to be used by clients, who will have the static import libraries as well.
Snippets as follows:
struct __declspec(dllexport) Data
{
double dataA;
double dataB;
Data(double _a, double _b) : dataA(_a), dataB(_b) {}
double helperMethod(double param1, double param2) { return dataA + dataB; }
};
struct __declspec(dllexport) AggData
{
double dataX;
double dataY;
Data aStructData;
AggData(double _x, double _y) : dataX(_x), dataY(_y), aStructData(0.0, 0.0) {}
double helperMethod(double param1, double param2) { return dataX + dataY; }
};
class __declspec(dllexport) IModel
{
public:
virtual Data returnSomeData() = 0;
virtual AggData returnSomeOtherData() = 0;
};
class __declspec(dllexport) Model : public IModel
{
public:
Data returnSomeData();
AggData returnSomeOtherData();
};
My main question is: Do the headers and the import libraries guarantee that clients can use my classes as intended, i.e., no corruption of data due to ABI issues?
This question and its answer seemed close to what I'm looking for, but there's no mention of whether an import library can solve the virtual function issue:
Passing struct by value from an explicitly loaded dll built with a different compiler
A related question: If I distributed only the headers without import libraries, and assuming there were no virtual functions, will it be sufficient for use? I think this is just a question about struct memory layout across compilers, but I'm not clear on it either.
Read these other questions, but didn't quite see an answer (or didn't realise if I saw one):
C++ define class member struct and return it in a member function
How to export/import a C struct from a DLL/ to a console application using __declspec( dllexport/import )

Dealing with C library anonymous struct types in C++

We have a big, old C++ application with a lot of legacy code and a few external libraries written in C. These libraries are very rarely updated - only if we find a bug and the vendor supplies a patch. This happened last week with one library, and upon integrating the new version we found out that if we don't modify the library locally (which we apparently did with the last version) our build breaks with this error message:
non-local function ‘static E* MyCls::myFct(<anonymous struct>*)’ uses anonymous type
This is due to the library declaring a number of handle types like this:
#define _Opaque struct {unsigned long x;} *
typedef _Opaque Handle;
typedef _Opaque Request;
which we use on our side in some classes' function signatures:
class MyCls {
public:
static void* myFct(Handle handle);
...
}
This produces the error above because the compiler can't create a proper name-mangled name for the function(s) as the _Opaque struct has no name.
Our current workaround for this is to patch the library header file, explicitly giving the struct a name:
//#define _Opaque struct {unsigned long x;} * //Replaced by typedef below!
typedef struct __Opaque {unsigned long x;} * _Opaque;
This is obviously bad because we don't want to touch the library if possible. Another even worse option would be to convert the types to void* in all function signatures and cast them back to their respective types. And there's the worst option to rewrite every affected function in pure C...
So, my question is: Is there any better option than patching the library? Is there an easy solution I am overlooking? What would be the best way to solve this?
You can accomplish this with a minimal change to the #define line, exploiting the rule in 7.1.3:8 that the first typedef-name declared by the declaration to be
that class type (or enum type) is used to denote the class type (or enum type) for linkage purposes only:
#define MAKE_DUMMY2(line) dummy_ ## line
#define MAKE_DUMMY(line) MAKE_DUMMY2(line)
#define _Opaque struct {unsigned long x;} MAKE_DUMMY(__LINE__), *
This gives Handle and Request etc. minimal linkage.
You can introduce names by declaring new types, which simply contain these elements. Use those types for your parameters.
namespace MON {
struct t_handle {
Handle handle;
};
class MyCls {
public:
static void* myFct(t_handle handle);
...
};
}
If you're willing to modify your methods on the interface, you can do slightly better than void *:
struct CHandle {
void *p;
CHandle(void *p): p(p) { }
};
struct CRequest {
void *p;
CRequest(void *p): p(p) { }
};
static CHandle make(Handle handle) { return CHandle(handle); }
static Handle get(CHandle handle) { return static_cast<Handle>(handle.p); }
static CRequest make(Request request) { return CRequest(request); }
static Request get(CRequest request) { return static_cast<Request>(request.p); }
Here, CHandle and CRequest have linkage and so can be used in your method signatures; the overloads of make and get have internal linkage and so can interface with the anonymous types. You can put this in a header, even the static functions.
You'll have to modify your code so that when e.g. MyCls::myFct calls into the library, you wrap parameters with get and return values with make.
This seems to work:
class MyCls {
public:
typedef _Opaque MHandle;
static void* myFct(MHandle handle) {
return 0;
}
};

Wrapping C++ class API for C consumption

I have a set of related C++ classes which must be wrapped and exported from a DLL in such a way that it can be easily consumed by C / FFI libraries. I'm looking for some "best practices" for doing this. For example, how to create and free objects, how to handle base classes, alternative solutions, etc...
Some basic guidelines I have so far is to convert methods into simple functions with an extra void* argument representing the 'this' pointer, including any destructors. Constructors can retain their original argument list, but must return a pointer representing the object. All memory should be handled via the same set of process-wide allocation and free routines, and should be hot-swappable in a sense, either via macros or otherwise.
Foreach public method you need a C function.
You also need an opaque pointer to represent your class in the C code.
It is simpler to just use a void* though you could build a struct that contains a void* and other information (For example if you wanted to support arrays?).
Fred.h
--------------------------------
#ifdef __cplusplus
class Fred
{
public:
Fred(int x,int y);
int doStuff(int p);
};
#endif
//
// C Interface.
typedef void* CFred;
//
// Need an explicit constructor and destructor.
extern "C" CFred newCFred(int x,int y);
extern "C" void delCFred(CFred);
//
// Each public method. Takes an opaque reference to the object
// that was returned from the above constructor plus the methods parameters.
extern "C" int doStuffCFred(CFred,int p);
The the implementation is trivial.
Convert the opaque pointer to a Fred and then call the method.
CFred.cpp
--------------------------------
// Functions implemented in a cpp file.
// But note that they were declared above as extern "C" this gives them
// C linkage and thus are available from a C lib.
CFred newCFred(int x,int y)
{
return reinterpret_cast<void*>(new Fred(x,y));
}
void delCFred(CFred fred)
{
delete reinterpret_cast<Fred*>(fred);
}
int doStuffCFred(CFred fred,int p)
{
return reinterpret_cast<Fred*>(fred)->doStuff(p);
}
While Loki Astari's answer is very good, his sample code puts the wrapping code inside the C++ class. I prefer to have the wrapping code in a separate file. Also I think it is better style to prefix the wrapping C functions with the class name.
The following blog posts shows how to do that:
http://blog.eikke.com/index.php/ikke/2005/11/03/using_c_classes_in_c.html
I copied the essential part because the blog is abandoned and might finally vanish (credit to Ikke's Blog):
First we need a C++ class, using one header file (Test.hh)
class Test {
public:
void testfunc();
Test(int i);
private:
int testint;
};
and one implementation file (Test.cc)
#include <iostream>
#include "Test.hh"
using namespace std;
Test::Test(int i) {
this->testint = i;
}
void Test::testfunc() {
cout << "test " << this->testint << endl;
}
This is just basic C++ code.
Then we need some glue code. This code is something in-between C and C++. Again, we got one header file (TestWrapper.h, just .h as it doesn't contain any C++ code)
typedef void CTest;
#ifdef __cplusplus
extern "C" {
#endif
CTest * test_new(int i);
void test_testfunc(const CTest *t);
void test_delete(CTest *t);
#ifdef __cplusplus
}
#endif
and the function implementations (TestWrapper.cc, .cc as it contains C++ code):
#include "TestWrapper.h"
#include "Test.hh"
extern "C" {
CTest * test_new(int i) {
Test *t = new Test(i);
return (CTest *)t;
}
void test_testfunc(const CTest *test) {
Test *t = (Test *)test;
t->testfunc();
}
void test_delete(CTest *test) {
Test *t = (Test *)test;
delete t;
}
}
First, you might not need to convert all your methods to C functions. If you can simplify the API and hide some of the C++ interface, it is better, since you minimize the chance to change the C API when you change C++ logic behind.
So think of a higher level abstraction to be provided through that API. Use that void* solution you described. It looks to me the most appropriate (or typedef void* as HANDLE :) ).
Some opinions from my experience:
functions should return codes to represent errors. It's useful to have a function returning error description in string form. All other return values should be out parameters.
E.g.:
C_ERROR BuildWidget(HUI ui, HWIDGET* pWidget);
put signatures into structures/classes your handles pointer to for checking handles on validness.
E.g. your function should look like:
C_ERROR BuildWidget(HUI ui, HWIDGET* pWidget){
Ui* ui = (Ui*)ui;
if(ui.Signature != 1234)
return BAD_HUI;
}
objects should be created and released using functions exported from DLL, since memory allocation method in DLL and consuming app can differ.
E.g.:
C_ERROR CreateUi(HUI* ui);
C_ERROR CloseUi(HUI hui); // usually error codes don't matter here, so may use void
if you are allocating memory for some buffer or other data that may be required to persist outside of your library, provide size of this buffer/data. This way users can save it to disk, DB or wherever they want without hacking into your internals to find out actual size. Otherwise you'll eventually need to provide your own file I/O api which users will use only to convert your data to byte array of known size.
E.g.:
C_ERROR CreateBitmap(HUI* ui, SIZE size, char** pBmpBuffer, int* pSize);
if your objects has some typical representation outside of your C++ library, provide a mean of converting to this representation (e.g. if you have some class Image and provide access to it via HIMG handle, provide functions to convert it to and from e.g. windows HBITMAP). This will simplify integration with existing API.
E.g.
C_ERROR BitmapToHBITMAP(HUI* ui, char* bmpBuffer, int size, HBITMAP* phBmp);
Use vector (and string::c_str) to exchange data with non C++ APIs. (Guideline #78 from C++ Coding Standards, H. Sutter/ A. Alexandrescu).
PS It's not that true that "constructors can retain their original argument list". This is only true for argument types which are C-compatible.
PS2 Of course, listen to Cătălin and keep your interface as small and simple as possible.
This may be of interest: "Mixing C and C++" at the C++ FAQ Lite. Specifically [32.8] How can I pass an object of a C++ class to/from a C function?

How to model an OO style interface for C functions?

I have a C module which is created by the Real-time Workshop based on a Simulink Model.
This modules provides three public functions:
int init();
int calc(double *inputarray, double *outputarray);
int term();
Based on the contents of the outputarray, I can model a class called OutputThing.
I want to integrate those functions in a wrapper class called WrapperModule.
Right now I have a class that looks like this:
class WrapperModule {
public:
int initialize();
OutputThing calc(...);
int terminate();
};
My problem is, how to properly design a wrapper method for the calc() Function. I want to avoid
to create a method with an array/vector as its single argument. But identifying the correct arguments
from the vector is tricky and I dislike the idea of having a method with 6 or more arguments.
Bertrand Meyer in his OOSC book suggests the use of setter methods. Something like:
class WrapperModule {
public:
int initialize();
void set_foo(double f);
void set_bar(double b);
OutputThing calc();
int terminate();
};
Any ideas? I'm not sure which approach would be better.
If you are able to also abstract inputarray to an InputThing class I'd suggest the following. This also better encapsulates the initialisation/termination using C++ construction/destruction.
class WrapperModule {
public:
// Calls init()
WrapperModule();
// Calls term()
~WrapperModule();
// Calls calc()
OutputThing calculate(const InputThing& inputThing);
};
If necessary, InputThing could have accessor and mutator (get/set) functions to prevent it needing a constructor taking many arguments.