Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Allow my C++ library to work with C (reduced function sets)

I've been wanting to build a shared library of which will utilize classes to keep its functioning clean (it may require many inputs or processing), although I still wish to target for C platforms.

If I apply extern "C" {} over all my prototypes, and provide in example a set of exposed functions that mimick the class functions so that objects are not "required" to use my library, will those normal functions work in C programs that will link to it?

like image 295
Alexander Avatar asked Mar 30 '11 12:03

Alexander


2 Answers

If you create a dll in the fasion you described, that is, all interfaces are extern "C" and all types in interfaces are POD's then yes, you'll practically have no problem using it in C or .NET

Example:

class MyClass
{
 public:
    MyClass(float x) {...}
    void method(int x) {...}
    ~MyClass() {...}
};

#define MYAPI extern "C" __declspec(dllexport) //or whatever the syntax is for your compiler

MYAPI MyClass* CreateMyClass(float x)
{
    return new MyClass(x);    
}

MYAPI void MyClass_method(MyClass* p, int x)
{
   return p->method(x);
}

MYAPI void DestroyMyClass(MyClass* p )
{
   delete p;
}
like image 187
Armen Tsirunyan Avatar answered Oct 20 '22 10:10

Armen Tsirunyan


You may need to have separate header files for your C sources to include. The C headers should not have any C++ code that the C compiler might be expected to parse. In there, you would provide the C interface to your C++ library. By providing the extern "C" modifier, as you indicate you would do, to the function declarations in this header you tell the compiler to make the linkage work for C programs.

So if you need the C program to hold a reference to an object, just pass it back and forth through the C interface as a void * pointer. In C you just treat it as a magic cookie.

Other posts speak to exposing the interface through a DLL, which is also useful knowledge but not strictly speaking to the (standard) language aspects.

Edit

Aw heck. The extern "C" part is C++ syntax. So, on the C++ side you must declare the C interface functions with extern "C" but on the C side you can't have that syntax. You can make this happen by the common idiom:

#ifdef __cplusplus
extern "C" {
#endif
void foo();
#ifdef __cplusplus
}
#endif
like image 33
gregg Avatar answered Oct 20 '22 08:10

gregg