C wrapper for C++ class with stack allocation - c++

Let's say we have a C++ library with a class like this:
class TheClass {
public:
TheClass() { ... }
void magic() { ... }
private:
int x;
}
Typical usage of this class would include stack allocation:
TheClass object;
object.magic();
We need to create a C wrapper for this class. The most common approach looks like this:
struct TheClassH;
extern "C" struct TheClassH* create_the_class() {
return reinterpret_cast<struct TheClassH*>(new TheClass());
}
extern "C" void the_class_magic(struct TheClassH* self) {
reinterpret_cast<TheClass*>(self)->magic();
}
However, it requires heap allocation, which is clearly not desired for such a small class.
I'm searching for an approach to allow stack allocation of this class from C code. Here is what I can think of:
struct TheClassW {
char space[SIZEOF_THECLASS];
}
void create_the_class(struct TheClassW* self) {
TheClass* cpp_self = reinterpret_cast<TheClass*>(self);
new(cpp_self) TheClass();
}
void the_class_magic(struct TheClassW* self) {
TheClass* cpp_self = reinterpret_cast<TheClass*>(self);
cpp_self->magic();
}
It's hard to put real content of the class in the struct's fields. We can't just include C++ header because C wouldn't understand it, so it would require us to write compatible C headers. And this is not always possible. I think C libraries don't really need to care about content of structs.
Usage of this wrapper would look like this:
TheClassW object;
create_the_class(&object);
the_class_magic(&object);
Questions:
Does this approach have any dangers or drawbacks?
Is there an alternative approach?
Are there any existing wrappers that use this approach?

You can use placement new in combination of alloca to create an object on the stack. For Windows there is _malloca. The importance here is that alloca, and malloca align memory for you accordingly and wrapping the sizeof operator exposes the size of your class portably. Be aware though that in C code nothing happens when your variable goes out of scope. Especially not the destruction of your object.
main.c
#include "the_class.h"
#include <alloca.h>
int main() {
void *me = alloca(sizeof_the_class());
create_the_class(me, 20);
if (me == NULL) {
return -1;
}
// be aware return early is dangerous do
the_class_magic(me);
int error = 0;
if (error) {
goto fail;
}
fail:
destroy_the_class(me);
}
the_class.h
#ifndef THE_CLASS_H
#define THE_CLASS_H
#include <stddef.h>
#include <stdint.h>
#ifdef __cplusplus
class TheClass {
public:
TheClass(int me) : me_(me) {}
void magic();
int me_;
};
extern "C" {
#endif
size_t sizeof_the_class();
void *create_the_class(void* self, int arg);
void the_class_magic(void* self);
void destroy_the_class(void* self);
#ifdef __cplusplus
}
#endif //__cplusplus
#endif // THE_CLASS_H
the_class.cc
#include "the_class.h"
#include <iostream>
#include <new>
void TheClass::magic() {
std::cout << me_ << std::endl;
}
extern "C" {
size_t sizeof_the_class() {
return sizeof(TheClass);
}
void* create_the_class(void* self, int arg) {
TheClass* ptr = new(self) TheClass(arg);
return ptr;
}
void the_class_magic(void* self) {
TheClass *tc = reinterpret_cast<TheClass *>(self);
tc->magic();
}
void destroy_the_class(void* self) {
TheClass *tc = reinterpret_cast<TheClass *>(self);
tc->~TheClass();
}
}
edit:
you can create a wrapper macro to avoid separation of creation and initialization. you can't use do { } while(0) style macros because it will limit the scope of the variable. There is other ways around this but this is highly dependent on how you deal with errors in the code base. A proof of concept is below:
#define CREATE_THE_CLASS(NAME, VAL, ERR) \
void *NAME = alloca(sizeof_the_class()); \
if (NAME == NULL) goto ERR; \
// example usage:
CREATE_THE_CLASS(me, 20, fail);
This expands in gcc to:
void *me = __builtin_alloca (sizeof_the_class()); if (me == __null) goto fail; create_the_class(me, (20));;

There are alignment dangers. But maybe not on your platform. Fixing this may require platform specific code, or C/C++ interop that is not standardized.
Design wise, have two types. In C, it is struct TheClass;. In C++, struct TheClass has a body.
Make a struct TheClassBuff{char buff[SIZEOF_THECLASS];};
TheClass* create_the_class(struct TheClassBuff* self) {
return new(self) TheClass();
}
void the_class_magic(struct TheClass* self) {
self->magic();
}
void the_class_destroy(struct TheClass* self) {
self->~TheClass();
}
C is supposed to make the buff, then create a handle from it and interact using it. Now usually that isn't required as reinterpreting pointer to theclassbuff will work, but I think that is undefined behaviour technically.

Here is another approach, which may or may not be acceptable, depending on the application specifics. Here we basically hide the existence of TheClass instance from C code and encapsulate every usage scenario of TheClass in a wrapper function. This will become unmanageable if the number of such scenarios is too large, but otherwise may be an option.
The C wrapper:
extern "C" void do_magic()
{
TheClass object;
object.magic();
}
The wrapper is trivially called from C.
Update 2/17/2016:
Since you want a solution with a stateful TheClass object, you can follow the basic idea of your original approach, which was further improved in another answer. Here is yet another spin on that approach, where the size of the memory placeholder, provided by the C code, is checked to ensure it is sufficiently large to hold an instance of TheClass.
I would say that the value of having a stack-allocated TheClass instance is questionable here, and it is a judgement call depending on the application specifics, e.g. performance. You still have to call the de-allocation function, which in turn calls the destructor, manually, since it is possible that TheClass allocates resources that have to be released.
However, if having a stack-allocated TheClass is important, here is another sketch.
The C++ code to be wrapped, along with the wrapper:
#include <new>
#include <cstring>
#include <cstdio>
using namespace std;
class TheClass {
public:
TheClass(int i) : x(i) { }
// cout doesn't work, had to use puts()
~TheClass() { puts("Deleting TheClass!"); }
int magic( const char * s, int i ) { return 123 * x + strlen(s) + i; }
private:
int x;
};
extern "C" TheClass * create_the_class( TheClass * self, size_t len )
{
// Ensure the memory buffer is large enough.
if (len < sizeof(TheClass)) return NULL;
return new(self) TheClass( 3 );
}
extern "C" int do_magic( TheClass * self, int l )
{
return self->magic( "abc", l );
}
extern "C" void delete_the_class( TheClass * self )
{
self->~TheClass(); // 'delete self;' won't work here
}
The C code:
#include <stdio.h>
#define THE_CLASS_SIZE 10
/*
TheClass here is a different type than TheClass in the C++ code,
so it can be called anything else.
*/
typedef struct TheClass { char buf[THE_CLASS_SIZE]; } TheClass;
int do_magic(TheClass *, int);
TheClass * create_the_class(TheClass *, size_t);
void delete_the_class(TheClass * );
int main()
{
TheClass mem; /* Just a placeholder in memory for the C++ TheClass. */
TheClass * c = create_the_class( &mem, sizeof(TheClass) );
if (!c) /* Need to make sure the placeholder is large enough. */
{
puts("Failed to create TheClass, exiting.");
return 1;
}
printf("The magic result is %d\n", do_magic( c, 232 ));
delete_the_class( c );
return 0;
}
This is just a contrived example for illustration purposes. Hopefully it is helpful. There may be subtle problems with this approach, so testing on your specific platform is highly important.
A few additional notes:
THE_CLASS_SIZE in the C code is just the size of a memory buffer in which
a C++'s TheClass instance is to be allocated; we are fine as long as
the size of the buffer is sufficient to hold a C++'s TheClass
Because TheClass in C is just a memory placeholder, we might just as
well use a void *, possibly typedef'd, as the parameter type in the
wrapper functions instead of TheClass. We would reinterpret_cast
it in the wrapper code, which would actually make the code clearer:
pointers to C's TheClass are essentially reinterpreted as C++'s TheClass anyway.
There is nothing to prevent C code from passing a TheClass* to the
wrapper functions that doesn't actually point to a C++'s TheClass
instance. One way to solve this is to store pointers to properly
initialized C++ TheClass instances in some sort of a data structure
in the C++ code and return to the C code handles that can be used to
look up these instances.
To use couts in the C++ wrapper we need to link with
the C++ standard lib when building an executable. For example, if
the C code is compiled into main.o and C++ into lib.o, then on
Linux or Mac we'd do gcc -o junk main.o lib.o -lstdc++.

It worth to keep each piece of knowledge in a single place, so I would suggest to make a class code "partially readable" for C. One may employ rather simple set of macro definitions to enable it to be done in short and standard words. Also, a macro may be used to invoke constructor and destructor at the beginning and the end of stack-allocated object's life.
Say, we include the following universal file first into both C and C++ code:
#include <stddef.h>
#include <alloca.h>
#define METHOD_EXPORT(c,n) (*c##_##n)
#define CTOR_EXPORT(c) void (c##_construct)(c* thisPtr)
#define DTOR_EXPORT(c) void (c##_destruct)(c* thisPtr)
#ifdef __cplusplus
#define CL_STRUCT_EXPORT(c)
#define CL_METHOD_EXPORT(c,n) n
#define CL_CTOR_EXPORT(c) c()
#define CL_DTOR_EXPORT(c) ~c()
#define OPT_THIS
#else
#define CL_METHOD_EXPORT METHOD_EXPORT
#define CL_CTOR_EXPORT CTOR_EXPORT
#define CL_DTOR_EXPORT DTOR_EXPORT
#define OPT_THIS void* thisPtr,
#define CL_STRUCT_EXPORT(c) typedef struct c c;\
size_t c##_sizeof();
#endif
/* To be put into a C++ implementation coce */
#define EXPORT_SIZEOF_IMPL(c) extern "C" size_t c##_sizeof() {return sizeof(c);}
#define CTOR_ALIAS_IMPL(c) extern "C" CTOR_EXPORT(c) {new(thisPtr) c();}
#define DTOR_ALIAS_IMPL(c) extern "C" DTOR_EXPORT(c) {thisPtr->~c();}
#define METHOD_ALIAS_IMPL(c,n,res_type,args) \
res_type METHOD_EXPORT(c,n) args = \
call_method(&c::n)
#ifdef __cplusplus
template<class T, class M, M m, typename R, typename... A> R call_method(
T* currPtr, A... args)
{
return (currPtr->*m)(args...);
}
#endif
#define OBJECT_SCOPE(t, v, body) {t* v = alloca(t##_sizeof()); t##_construct(v); body; t##_destruct(v);}
Now we can declare our class (the header is useful both in C and C++, too)
/* A class declaration example */
#ifdef __cplusplus
class myClass {
private:
int y;
public:
#endif
/* Also visible in C */
CL_STRUCT_EXPORT(myClass)
void CL_METHOD_EXPORT(myClass,magic) (OPT_THIS int c);
CL_CTOR_EXPORT(myClass);
CL_DTOR_EXPORT(myClass);
/* End of also visible in C */
#ifdef __cplusplus
};
#endif
Here is the class implementation in C++:
myClass::myClass() {std::cout << "myClass constructed" << std::endl;}
CTOR_ALIAS_IMPL(myClass);
myClass::~myClass() {std::cout << "myClass destructed" << std::endl;}
DTOR_ALIAS_IMPL(myClass);
void myClass::magic(int n) {std::cout << "myClass::magic called with " << n << std::endl;}
typedef void (myClass::* myClass_magic_t) (int);
void (*myClass_magic) (myClass* ptr, int i) =
call_method<myClass,myClass_magic_t,&myClass::magic,void,int>;
and this is a using C code example
main () {
OBJECT_SCOPE(myClass, v, {
myClass_magic(v,178);
})
}
It's short and working! (here's the output)
myClass constructed
myClass::magic called with 178
myClass destructed
Note that a variadic template is used and this requires c++11. However, if you don't want to use it, a number of fixed-size templates ay be used instead.

Here's how one might do it safely and portably.
// C++ code
extern "C" {
typedef void callback(void* obj, void* cdata);
void withObject(callback* cb, void* data) {
TheClass theObject;
cb(&theObject, data);
}
}
// C code:
struct work { ... };
void myCb (void* object, void* data) {
struct work* work = data;
// do whatever
}
// elsewhere
struct work work;
// initialize work
withObject(myCb, &work);

What I did in alike situation is something like:
(I omit static_cast, extern "C")
class.h:
class TheClass {
public:
TheClass() { ... }
void magic() { ... }
private:
int x;
}
class.cpp
<actual implementation>
class_c_wrapper.h
void* create_class_instance(){
TheClass instance = new TheClass();
}
void delete_class_instance(void* instance){
delete (TheClass*)instance;
}
void magic(void* instance){
((TheClass*)instance).magic();
}
Now, you stated that you need stack allocation. For this I can suggest rarely used option of new: placement new. So you'd pass additional parameter in create_class_instance() that is pointing to an allocated buffer enough to store class instance, but on stack.

This is how I would solve the issue (basic idea is to let interprete C and C++ the same memory and names differently):
TheClass.h:
#ifndef THECLASS_H_
#define THECLASS_H_
#include <stddef.h>
#define SIZEOF_THE_CLASS 4
#ifdef __cplusplus
class TheClass
{
public:
TheClass();
~TheClass();
void magic();
private:
friend void createTheClass(TheClass* self);
void* operator new(size_t, TheClass*) throw ();
int x;
};
#else
typedef struct TheClass {char _[SIZEOF_THE_CLASS];} TheClass;
void create_the_class(struct TheClass* self);
void the_class_magic(struct TheClass* self);
void destroy_the_class(struct TheClass* self);
#endif
#endif /* THECLASS_H_ */
TheClass.cpp:
TheClass::TheClass()
: x(0)
{
}
void* TheClass::operator new(size_t, TheClass* self) throw ()
{
return self;
}
TheClass::~TheClass()
{
}
void TheClass::magic()
{
}
template < bool > struct CompileTimeCheck;
template < > struct CompileTimeCheck < true >
{
typedef bool Result;
};
typedef CompileTimeCheck< SIZEOF_THE_CLASS == sizeof(TheClass) >::Result SizeCheck;
// or use static_assert, if available!
inline void createTheClass(TheClass* self)
{
new (self) TheClass();
}
extern "C"
{
void create_the_class(TheClass* self)
{
createTheClass(self);
}
void the_class_magic(TheClass* self)
{
self->magic();
}
void destroy_the_class(TheClass* self)
{
self->~TheClass();
}
}
The createTheClass function is for friendship only - I wanted to avoid the C wrapper functions to be publicly visible within C++. I caught up the array variant of the TO, because I consider this better readable than the alloca approach. Tested with:
main.c:
#include "TheClass.h"
int main(int argc, char*argv[])
{
struct TheClass c;
create_the_class(&c);
the_class_magic(&c);
destroy_the_class(&c);
}

Related

Passing a pointer to a C++ member function to a C API library

First post here and I've tried to look at previous similar posts but none of them seem to work or do quite what I want.
I have some C code, call it library.c. I've removed a lot of the code and simplified it.
// libary.c
// A callback function that takes an int
void (*library_cb)(int);
void init(void (*cb())) {
// some other code
library_cb = cb;
}
void sample() {
int data;
// execute a bunch of code and then call the callback function
(*library_cb)(data);
}
Now I have c++ code that defines the callback function that I want to pass to the code in library.c
// someclass.cpp
class SomeClass {
public:
SomeClass() {
};
~SomeClass() {
};
void callback(int data) {
// Do some stuff
}
};
And then in main.cpp I want to do something like
// main.cpp
extern "C" {
#include "library.h"
}
#include "someclass.h"
SomeClass some_class;
int main() {
init(&some_class.callback) // obviously doesn't work
while(true) {
sample(); // this would call callback in SomeClass
}
}
Now I know one solution is to define callback as
static void callback(int data)
But I was wondering if there are any other ways to do this. From what I read, std::function might help or std::mem_fn. But I can't seem to figure out how.
I haven't included the header files and I wrote this code as an example of my problem so there might be some syntax errors, but hopefully the question/goal is clear.
Edit:
I should have mentioned that I can edit the c library.
Reading the answers, it seems I can change the c library to also accept a void* pointer to the class object to get this to work. Could someone show me an example for this case please? I'm super new to interfacing c code with c++.
Passing a pointer to a C++ member function to a C API library
... is not possible.
From what I read, std::function might help or std::mem_fn
Neither of those can be called in C either, but keep reading 'till the end.
C only has regular non-member function pointers so those are the only function pointers that a C program can call. In C++, such pointer can point to either a free function or a static member function.
Within the C++ implementation of such static- or non-member function you can of course do anything within the power of C++ (although, letting an exception escape the function would be bad), so you can indeed call a non-static member function there.
But to call a non-static member function, there needs to be an instance. A static object is a trivial solution, but is not very flexible and only useful in a few situations.
Well designed callback API's in C let user of the API register a generic data pointer (i.e. void*) in addition to a function pointer, and that data pointer will be forwarded to the callback. This design allows the callbacks to be stateful - the state is stored in the pointed object. When using such C API, you can pass a pointer to an object whose member functions the callback can then call. Or, you could pass a data pointer to a std::function or some other stateful type erasing function wrapper, and use a generic free function that simply forwards the call to the wrapper.
Your C API is not very usable. Here's how I'd do it:
The callback must at least take a user-provided void* parameter that the library doesn't interpret in any way. Without this parameter, callbacks are useless. Yes, they really are useless and the users of your API users will hate you for that.
If you want the callback to be able to modify the value of its parameter, you can pass the address of the void* parameter. That is useful for e.g. allocation-on-registration and similar uses where the parameter changes during callback's execution. This makes the library completely decoupled from the use of the pointer: not only it doesn't interpret the pointer, but it doesn't keep its value constant.
The library API symbols are all prefixed to prevent collisions in the global namespace.
Typedefs are used as needed to ensure readable code. Typing out function pointer types is tedious at best.
The header is guarded against multiple-inclusion, i.e. it must be OK to include it multiple times in a translation unit, without any errors.
The header declares a C interface when compiled in a C++ translation unit, since, well: the interface is a C one. C++ mangles the symbol names and the header will declare binary-incompatible symbols.
The header declares the C interface noexcept in C++11. This presents optimization opportunities to the C++ users.
Consider the library registering more than one callback, as well as possibly invoking the callback on registration and deregistration: those make interoperation with other programming languages much easier.
library.h - usable from C and C++
#pragma once
#ifdef __cplusplus
extern "C" {
#pragma GCC diagnostic push
// clang erroneously issues a warning in spite of extern "C" linkage
#pragma GCC diagnostic ignored "-Wc++17-compat-mangling"
#endif
#ifndef LIBRARY_NOEXCEPT
#if __cplusplus >= 201103L
// c.f. https://stackoverflow.com/q/24362616/1329652
#define LIBRARY_NOEXCEPT noexcept
#else
#define LIBRARY_NOEXCEPT
#endif
#endif
enum library_register_enum { LIBRARY_REG_FAILURE = 0, LIBRARY_REG_SUCCESS = 1, LIBRARY_REG_DUPLICATE = -1 };
enum library_call_enum { LIBRARY_SAMPLE, LIBRARY_REGISTER, LIBRARY_DEREGISTER };
typedef enum library_register_enum library_register_result;
typedef enum library_call_enum library_call_type;
#if __cplusplus >= 201103L
void library_callback_dummy(library_call_type, int, void**) LIBRARY_NOEXCEPT;
using library_callback = decltype(&library_callback_dummy);
#else
typedef void (*library_callback)(library_call_type, int, void**);
#endif
void library_init(void) LIBRARY_NOEXCEPT;
library_register_result library_register_callback(library_callback cb, void *cb_param) LIBRARY_NOEXCEPT;
void library_deregister_callback(library_callback cb, void *cb_param) LIBRARY_NOEXCEPT;
void library_deregister_any_callback(library_callback cb) LIBRARY_NOEXCEPT;
void library_deregister_all_callbacks(void) LIBRARY_NOEXCEPT;
void library_deinit(void) LIBRARY_NOEXCEPT;
void library_sample(void) LIBRARY_NOEXCEPT;
#ifdef __cplusplus
#pragma GCC diagnostic pop
}
#endif
Below note that the private data and functions, i.e. those not part of the API, are declared so (static).
library.c - the implementation
#include "library.h"
#include <stdlib.h>
typedef struct callback_s {
struct callback_s *next;
library_callback function;
void *parameter;
} callback;
static callback *cb_head;
void library_init(void) { /* some other code */
}
void library_deinit(void) { library_deregister_all_callbacks(); }
library_register_result library_register_callback(library_callback cb, void *cb_param) {
callback *el = cb_head;
while (el) {
if (el->function == cb && el->parameter == cb_param) return LIBRARY_REG_DUPLICATE;
el = el->next;
}
el = malloc(sizeof(callback));
if (!el) return LIBRARY_REG_FAILURE;
el->next = cb_head;
el->function = cb;
el->parameter = cb_param;
cb_head = el;
cb(LIBRARY_REGISTER, 0, &el->parameter);
return LIBRARY_REG_SUCCESS;
}
static int match_callback(const callback *el, library_callback cb, void *cb_param) {
return el && el->function == cb && el->parameter == cb_param;
}
static int match_any_callback(const callback *el, library_callback cb, void *cb_param) {
return el && el->function == cb;
}
static int match_all_callbacks(const callback *el, library_callback cb, void *cb_param) {
return !!el;
}
typedef int (*matcher)(const callback *, library_callback, void *);
static void deregister_callback(matcher match, library_callback cb, void *cb_param) {
callback **p = &cb_head;
while (*p) {
callback *el = *p;
if (match(el, cb, cb_param)) {
*p = el->next;
el->function(LIBRARY_DEREGISTER, 0, &el->parameter);
free(el);
} else
p = &el->next;
}
}
void library_deregister_callback(library_callback cb, void *cb_param) {
deregister_callback(match_callback, cb, cb_param);
}
void library_deregister_any_callback(library_callback cb) {
deregister_callback(match_any_callback, cb, NULL);
}
void library_deregister_all_callbacks(void) {
deregister_callback(match_all_callbacks, NULL, NULL);
}
void library_sample(void) {
int data = 42;
// execute a bunch of code and then call the callback function
callback *el = cb_head;
while (el) {
el->function(LIBRARY_SAMPLE, data, &el->parameter);
el = el->next;
}
}
That way, the user registering the callback can pass arbitrary data to the callback. The library-using code would be implemented in C++ as follows:
// https://github.com/KubaO/stackoverflown/tree/master/questions/c-cpp-library-api-53643120
#include <iostream>
#include <memory>
#include <string>
#include "library.h"
struct Data {
std::string payload;
static int counter;
void print(int value) {
++counter;
std::cout << counter << ": " << value << ", " << payload << std::endl;
}
};
int Data::counter;
extern "C" void callback1(library_call_type type, int value, void **param) noexcept {
if (type == LIBRARY_SAMPLE) {
auto *data = static_cast<Data *>(*param);
data->print(value);
}
}
using DataPrintFn = std::function<void(int)>;
extern "C" void callback2(library_call_type type, int value, void **param) noexcept {
assert(param && *param);
auto *fun = static_cast<DataPrintFn *>(*param);
if (type == LIBRARY_SAMPLE)
(*fun)(value);
else if (type == LIBRARY_DEREGISTER) {
delete fun;
*param = nullptr;
}
}
void register_callback(Data *data) {
library_register_callback(&callback1, data);
}
template <typename F>
void register_callback(F &&fun) {
auto f = std::make_unique<DataPrintFn>(std::forward<F>(fun));
library_deregister_callback(callback2, f.get());
library_register_callback(callback2, f.release());
// the callback will retain the functor
}
int main() {
Data data;
data.payload = "payload";
library_init();
register_callback(&data);
register_callback([&](int value) noexcept { data.print(value); });
library_sample();
library_sample();
library_deinit(); // must happen before the 'data' is destructed
assert(data.counter == 4);
}

Assign templated implementation to previously declared function

I've got an .h file containing 2 different functions declaration:
#ifdef MY_HEADER
#define MY_HEADER
void a();
void b();
#endif
Now into .cpp file I want to implement those functions as different instances of another templated function:
#include "my_header.h"
namespace {
template<size_t N>
void c()
{
...
}
}
void (*a)() = c<42>;
void (*b)() = c<265>;
I'm getting an error message error: 'void (* a)()' redeclared as different kind of symbol. I've also tried a = c<42> and auto a = c<42> with no luck.
I know I can do it like this:
void a() {c<42>();}
void b() {c<265>();}
and I'm almost sure compiler will optimize this extra function call for me, but I'm wondering if there's a better way to declare this. I don't want to put c function itself into .h file either because this function is quite heavy and I don't want to have it recompiled in every source file using my header.
You just need to have the declarations of a and b match the definitions, so declare them as void(*)() variables, rather than void() functions.
The other answers suggesting std::function<void()> are ignoring that it is a very heavyweight option.
my_header.h
#ifdef MY_HEADER
#define MY_HEADER
extern void (*a)();
extern void (*b)();
#endif
my_impl.cpp
#include "my_header.h"
namespace {
template<size_t N>
void c()
{
...
}
}
void (*a)() = c<42>;
void (*b)() = c<265>;
See it live
You may want to forbid a and b from being modified, and declare them as void (* const)(), i.e. (const pointer) to (function).
extern void (* const a)();
...
void (* const a)() = c<42>;
...
// a = c<53>; // error: assignment of read-only variable 'a'
You can do the following:
Header file:
#ifndef MY_HEADER
#define MY_HEADER
#include <functional>
extern std::function<void()> a;
extern std::function<void()> b;
#endif
Implementation file:
#include "Header.h"
namespace {
template<size_t N>
void c() {
...
}
}
std::function<void()> a = std::bind(&c<42>);
std::function<void()> b = std::bind(&c<265>);
I'm wondering if there's a better way to declare this.
If you're looking for a more general-purpose higher wrapper for a function type, use std::function.
In your .h file, declare:
#include <functional>
std::function<void()> a;
In your .cpp file, assign your desired function to it:
a = c<42>;
a();
Be sure about the overhead of using std::function though, it can be quite expensive for such a trivial job.
This is working for me, might be a solution:
header.h
template<size_t N>
void c() {
...
}
main.cpp
#include "header.h"
void (*a)(void) = c<10>;
int main() {
a();
}

How to use c++ objects in c?

I have 2 projects decoder and dec in my visual studio. One has C code and other has C++ code using stl respectively.How do I instantiate the c++ classes in my c code inside decode project?
for e.g.
//instantiating object
reprVectorsTree *r1 = new reprVectorsTree(reprVectors1,8);
//using one of its function
r1->decode(code);
What do I need to do for this?
How do I access files from another project?
How do I make use of existing c++ code in C files?
--------edit----------
I have a class like this
class Node//possible point in our input space
{
public:
std::vector<float> valuesInDim;//values in dimensions
std::vector<bool> code;
Node(std::vector<float>value);
Node::Node(float x, float y);
Node::Node(std::vector<float> value,std::vector<bool> binary);
};
How do I use the above class in c++?
If C only allows structs how do I map it to a struct?
Give the C++ module a C interface:
magic.hpp:
struct Magic
{
Magic(char const *, int);
double work(int, int);
};
magic.cpp: (Implement Magic.)
magic_interface.h:
struct Magic;
#ifdef __cplusplus
extern "C" {
#endif
typedef Magic * MHandle;
MHandle create_magic(char const *, int);
void free_magic(MHandle);
double work_magic(MHandle, int, int);
#ifdef __cplusplus
}
#endif
magic_interface.cpp:
#include "magic_interface.h"
#include "magic.hpp"
extern "C"
{
MHandle create_magic(char const * s, int n) { return new Magic(s, n); }
void free_magic(MHandle p) { delete p; }
double work_magic(MHandle p, int a, int b) { return p->work(a, b); }
}
Now a C program can #include "magic_interface.h" and use the code:
MHandle h = create_magic("Hello", 5);
double d = work_magic(h, 17, 29);
free_magic(h);
(You might even want to define MHandle as void * and add casts everywhere so as to avoid declaring struct Magic in the C header at all.)
In simple terms, you just do these:
Write an interface function to convert all the class functions (constructor, destructor, member functions) as pure functions, and encapsulate them as extern "C"{ }
Convert the pointer to the class as pointer to void, and carefully use type-cast wherever you define the "pure functions"
Call the pure functions in the C-code.
For example here is my simple Rectangle class:
/*** Rectangle.h ***/
class Rectangle{
private:
double length;
double breadth;
public:
Rectangle(double iLength, double iBreadth);
~Rectangle();
double getLength();
double getBreadth();
};
/*** Rectangle.cpp ***/
#include "Rectangle.h"
#include <iostream>
extern "C" {
Rectangle::Rectangle(double l, double b) {
this->length = l;
this->breadth = b;
}
Rectangle::~Rectangle() {
std::cout << "Deleting object of this class Rectangle" << std::endl;
}
double Rectangle::getLength() {
return this->length;
}
double Rectangle::getBreadth() {
return this->breadth;
}
}
Now here is my interface to convert the class functions to pure functions. Notice how the pointer to the class is handled!
/*** RectangleInterface.h ***/
#ifdef __cplusplus
extern "C" {
#endif
typedef void * RHandle;
RHandle create_Rectangle(double l, double b);
void free_Rectangle(RHandle);
double getLength(RHandle);
double getBreadth(RHandle);
#ifdef __cplusplus
}
#endif
/*** RectangleInterface.cpp ***/
#include "RectangleInterface.h"
#include "Rectangle.h"
extern "C"
{
RHandle create_Rectangle(double l, double b){
return (Rectangle*) new Rectangle(l, b);
};
void free_Rectangle(RHandle p){
delete (Rectangle*) p;
}
double getLength(RHandle p){
return ((Rectangle*) p)->getLength();
}
double getBreadth(RHandle p){
return ((Rectangle*)p)->getBreadth();
}
}
Now I can use these interface functions in my ".c" file as shown below. I just have to include the RectangleInterface.h function here, and the rest is taken care by its functions.
/*** Main function call ***/
#include <stdio.h>
#include "RectangleInterface.h"
int main()
{
printf("Hello World!!\n");
RHandle myRec = create_Rectangle(4, 3);
printf("The length of the rectangle is %f\n", getLength(myRec));
printf("The area of the rectangle is %f\n", (getLength(myRec)*getBreadth(myRec)));
free_Rectangle(myRec);
return 0;
}
Make wrapper for instantiating C++ objects using C++ exported functions.And then call these functions from C code to generate objects.
Since one is function oriented and other is object oriented, you can use a few ideas in your wrapper:-
In order to copy class member, pass an equivalent prespecified struct from C code to corresponding C++ function in order to fetch the data.
Try using function pointers, as it will cut the cost, but be careful they can be exploited as well.
A few other ways.
you would need to write a wrapper in C.
something like this:
in class.h:
struct A{
void f();
}
in class.cpp:
void A::f(){
}
the wrapper.cpp:
#include "wrapper.h"
void fWrapper(struct A *a){a->f();};
struct A *createA(){
A *tmp=new A();
return tmp;
}
void deleteA(struct A *a){
delete a;
}
the wrapper.h for C:
struct A;
void fWrapper(struct A *a);
A *createA();
the C program:
#include "wrapper.h"
int main(){
A *a;
a=createA();
fWrapper(a);
deleteA(a);
}

How do I implement convenient logging without a Singleton?

My current implementation, simplified:
#include <string>
#include <memory>
class Log
{
public:
~Log() {
// closing file-descriptors, etc...
}
static void LogMsg( const std::string& msg )
{
static std::unique_ptr<Log> g_singleton;
if ( !g_singleton.get() )
g_singleton.reset( new Log );
g_singleton->logMsg( msg );
}
private:
Log() { }
void logMsg( const std::string& msg ) {
// do work
}
};
In general, I am satisfied with this implementation because:
lazy instantiation means I don't pay unless I use it
use of unique_ptr means automatic cleanup so valgrind is happy
relatively simple, easy-to-understand implementation
However, the negatives are:
singletons aren't conducive to unit-testing
dissonance in the back of my mind for introducing a pseudo-global (a bit of a code smell)
So here are my questions directed towards those developers who are successful in exorcising all singletons from their C++ code:
What kind of non-Singleton implementation do you use for application-wide logging?
Is the interface as simple and accessible as a Log::LogMsg() call above?
I want to avoid passing a Log instance all over my code, if at all possible - note: I am asking because, I, too, want to exorcise all Singletons from my code if there is a good, reasonable alternative.
First: the use of std::unique_ptr is unnecessary:
void Log::LogMsg(std::string const& s) {
static Log L;
L.log(s);
}
Produces exactly the same lazy initialization and cleanup semantics without introducing all the syntax noise (and redundant test).
Now that is out of the way...
Your class is extremely simple. You might want to build a slightly more complicated version, typical requirements for log messages are:
timestamp
level
file
line
function
process name / thread id (if relevant)
on top of the message itself.
As such, it is perfectly conceivable to have several objects with different parameters:
// LogSink is a backend consuming preformatted messages
// there can be several different instances depending on where
// to send the data
class Logger {
public:
Logger(Level l, LogSink& ls);
void operator()(std::string const& message,
char const* function,
char const* file,
int line);
private:
Level _level;
LogSink& _sink;
};
And you usually wrap the access inside a macro for convenience:
#define LOG(Logger_, Message_) \
Logger_( \
static_cast<std::ostringstream&>( \
std::ostringstream().flush() << Message_ \
).str(), \
__FUNCTION__, \
__FILE__, \
__LINE__ \
);
Now, we can create a simple verbose logger:
Logger& Debug() {
static Logger logger(Level::Debug, Console);
return logger;
}
#ifdef NDEBUG
# define LOG_DEBUG(_) do {} while(0)
#else
# define LOG_DEBUG(Message_) LOG(Debug(), Message_)
#endif
And use it conveniently:
int foo(int a, int b) {
int result = a + b;
LOG_DEBUG("a = " << a << ", b = " << b << " --> result = " << result)
return result;
}
The purpose of this rant ? Not all that is a global need be unique. The uniqueness of Singletons is generally useless.
Note: if the bit of magic involving std::ostringstream scares you, this is normal, see this question
I'd go with the simple, pragmatic solution:
you want a solution that is globally accessible. For the most part, I try to avoid globals, but for loggers, let's face it, it's usually impractical.
So, we do need something to be globally accessible.
But, we don't want the additional "there can be only one" restriction that a singleton confers. Some of your unit tests might want to instantiate their own private logger. Others might want to replace the global logger, perhaps.
So make it a global. A plain old simple global variable.
This still doesn't fully solve the problem with unit testing, admittedly, but we can't always have everything we want. ;)
As pointed out in the comment, you need to consider the initialization order for globals, which, in C++, is partly undefined.
In my code, that is generally not a problem, because I rarely have more than one global (my logger), and I stick rigidly to a rule of never allowing globals to depend on each others.
But it's something you have to consider, at least.
I really like the following interface since it uses streaming. Of course you can add channels, time and thread information to it. Another possible extension is to use the __FILE__ and __LINE__ macros and add it as parameters to the constructor. You could even add a variadic template function if you do not like the stream syntax. If you want to store some configuration you could add them to some static variables.
#include <iostream>
#include <sstream>
class LogLine {
public:
LogLine(std::ostream& out = std::cout) : m_Out(out) {}
~LogLine() {
m_Stream << "\n";
m_Out << m_Stream.rdbuf();
m_Out.flush();
}
template <class T>
LogLine& operator<<(const T& thing) { m_Stream << thing; return *this; }
private:
std::stringstream m_Stream;
std::ostream& m_Out;
//static LogFilter...
};
int main(int argc, char *argv[])
{
LogLine() << "LogLine " << 4 << " the win....";
return 0;
}
// file ILoggerImpl.h
struct ILoggerImpl
{
virtual ~ILoggerImpl() {}
virtual void Info(std::string s) = 0;
virtual void Warning(std::string s) = 0;
virtual void Error(std::string s) = 0;
};
// file logger.h //
#include "ILoggerImpl.h"
class CLogger: public ILoggerImpl
{
public:
CLogger():log(NULL) { }
//interface
void Info(std::string s) {if (NULL==log) return; log->Info(s); }
void Warning(std::string s) {if (NULL==log) return; log->Warning(s); }
void Error(std::string s) {if (NULL==log) return; log->Error(s); }
//
void BindImplementation(ILoggerImpl &ilog) { log = &ilog; }
void UnbindImplementation(){ log = NULL; }
private:
ILoggerImpl *log;
};
// file: loggers.h //
#include "logger.h"
extern CLogger Log1;
extern CLogger Log2;
extern CLogger Log3;
extern CLogger Log4;
extern CLogger LogB;
/// file: A.h //
#include "loggers.h"
class A
{
public:
void foo()
{
Log1.Info("asdhoj");
Log2.Info("asdhoj");
Log3.Info("asdhoj");
}
private:
};
/// file: B.h //
#include "loggers.h"
class B
{
public:
void bar()
{
Log1.Info("asdhoj");
Log2.Info("asdhoj");
LogB.Info("asdhoj");
a.foo();
}
private:
A a;
};
////// file: main.cpp ////////////////
#include "loggers.h"
#include "A.h"
#include "B.h"
#include "fileloger.h"
#include "xmllogger.h"
CLogger Log1;
CLogger Log2;
CLogger Log3;
CLogger Log4;
CLogger LogB;
// client code
int main()
{
std::unique_ptr<ILoggerImpl> filelog1(new CFileLogger("C:\\log1.txt"));
Log1.BindImplementation(*filelog1.get());
std::unique_ptr<ILoggerImpl> xmllogger2(new CXmlLogger("C:\\log2.xml"));
Log2.BindImplementation(*xmllogger2.get());
std::unique_ptr<ILoggerImpl> xmllogger3(new CXmlLogger("C:\\logB.xml"));
LogB.BindImplementation(*xmllogger3.get());
B b;
b.bar();
return 0;
};
// testing code
///////file: test.cpp /////////////////////////////////
#include "loggers.h"
CLogger Log1;
CLogger Log2;
CLogger Log3;
CLogger Log4;
int main()
{
run_all_tests();
}
///////file: test_a.cpp /////////////////////////////////
#include "A.h"
TEST(test1)
{
A a;
}
TEST(test2, A_logs_to_Log1_when_foo_is_called())
{
A a;
std::unique_ptr<ILoggerImpl> filelog1Mock(new CFileLoggerMock("C:\\log1.txt"));
Log1.BindImplementation(*filelog1.get());
EXPECT_CALL(filelog1Mock Info...);
a.foo();
Log1.UnbindImplementation();
}

Using a C++ class member function (cannot be static) as a C callback function

I have a C library function that expects a function pointer for callback, and I want to pass in a C++ member function. The C++ function modifies a member variable, so I can't use a static free function (as suggested in several similar posts). My attempt (shown below) fails with a compiler error.
This post comes closest to what I need:
Using a C++ class member function as a C callback function
How can I do this without static functions? Thanks!
test.h
#ifndef TEST_H_
#define TEST_H_
#ifdef __cplusplus
extern "C" {
#endif
typedef void (*handler_t)(int foo, void *bar);
void set_handler(handler_t h);
#ifdef __cplusplus
}
#endif
#endif
test.c
#include "test.h"
#include <stdlib.h>
static handler_t handler_ = NULL;
void set_handler(handler_t h) {
handler_ = h;
}
void handle_event(int foo, void *bar) {
if (handler_ != NULL) handler_(foo, bar);
}
test.cpp
#include "test.h"
#include <iostream>
using namespace std;
class Foo {
public:
Foo() : ctr_(0) {};
// handler needs to access non-static variable, so it can't be static
void handler(int foo, void *bar) { ++ctr_; }
private:
int ctr_;
};
int main(int argc, char **argv) {
// error: can't convert to "void (*)(int, void*)"
set_handler(&Foo::handler);
cout << "done" << endl;
return 0;
}
GCC barf
$ gcc test.cpp test.c
test.cpp: In function ‘int main(int, char**)’:
test.cpp:18: error: cannot convert ‘void (Foo::*)(int, void*)’ to ‘void (*)(int, void*)’ for argument ‘1’ to ‘void set_handler(void (*)(int, void*))’
It is not possible, at least with that handler_t signature.
While you can create a free function on your .cpp to wrap the member call, you need a pointer to the Foo instance:
void my_wrap(int foo, void* bar) {
Foo* some_foo_instance = ...;
some_foo_instance->handler(foo, bar);
}
int main(int argc, char **argv) {
set_handler(&my_wrap);
}
You need some void* to pass the Foo instance as a handler attribute:
// Header
typedef void (*handler_t)(int foo, void *bar, void* arg1);
void set_handler(handler_t h, void* arg1);
// Impl.
void set_handler(handler_t h, void* arg1) {
handler_ = h;
handler_arg1_ = arg1;
}
// cpp
void my_wrap(int foo, void* bar, void* arg1) {
Foo* some_foo_instance = static_cast<Foo*>(arg1);
some_foo_instance->handler(foo, bar);
}
// main
int main(int argc, char **argv) {
Foo some_concrete_instance;
set_handler(&my_wrap, static_cast<void*>(&some_concrete_instance));
}
The big question is how many times you need to call set_handler multiple times to call methods on different objects. If this answer is one, you can do something like this:
#include <boost/function.hpp>
class HandlerContext
{
static boost::function<void (int, void*)> s_func
static void forward(int foo, void* bar)
{
s_func(foo, bar);
}
public:
static void set(boost::function<int, void*> const& f)
{
s_func = f;
set_handler(&HandlerContext::forward);
}
};
If the answer is "more than once", you can have multiple forwarding functions that get their function objects out of an array. You will need to preassign slots in this case, because the function in use will indicate which callback to make.
This sentence:
I have a C library function
This means you can NOT pass it any C++ object.
If the library you are using is a C library it does not know about C++ so it can not using anything that is C++ it can only use C stuff.
You MUST make it call a free function in you code.
Now your free function can then call a method on an object (that is why C callbacks have a void* parameter (so you can pass context to the callback)).
Suppose you create a mapping function:
Foo *inst = // some instance of Foo you're keeping around...
void wrapper(int foo, void *bar){
inst->handler(foo, bar);
}
Then use wrapper as the callback. Instance semantics in a callback are kind of strange, so I'm not sure how you're going to be sure you bind to the correct instance -- if this is a singleton maybe that doesn't matter.
Here is an ugly hack I invented awhile ago to solve this problem:
#include <boost/function.hpp>
#include <boost/bind.hpp>
using ::boost::function;
using ::boost::bind;
typedef int (*callback_t)(const char *, int);
typedef function<int(const char *, int)> MyFTWFunction;
template <MyFTWFunction *callback>
class callback_binder {
public:
static int callbackThunk(const char *s, int i) {
return (*callback)(s, i);
}
};
extern void register_callback(callback_t f);
int random_func(const char *s, int i)
{
if (s && *s) {
return i;
} else {
return -1;
}
}
MyFTWFunction myfunc;
class FooClass {
public:
virtual int callme(const char *s, int x) { return 0; };
};
int main(int argc, const char *argv[])
{
FooClass foo;
myfunc = bind(&FooClass::callme, &foo, _1, _2);
register_callback(&callback_binder<&myfunc>::callbackThunk);
return 0;
}
This could probably be fixed to use stuff from TR1 and remove the dependency on Boost.
And also, of course, myfunc is a global variable. It has to be a global variable. You must have one global variable per different possible object you'd want to call back into. OTOH, you can have as many of these globals as you want.
The main issue here is that it is absolutely impossible to do what you want within the given constraints. The pointer to the object you want to call back into has to come from somewhere. In some languages (like Python for example) you can create a function on-the-fly that has it's own copy of the object pointer. This cannot be done in C++. All functions must exist completely at compile time. You cannot create new function instances at run time.
With C++0x, you can sort of create functions at runtime with lambda functions. But these functions have an unspecified type and there is absolutely no way you could ever then pass them to a C function and have it work. Lambda expressions are meant to be supplied as template parameters and it's pretty hard to use them for anything else because their address can't be taken, and even if it could you ccouldn't actually know what type the pointer is pointing to.
I highly recommend not using it. The little void * most callback interfaces allow you to specify that gets handed back to you along with the data is meant to hold an object pointer of some kind. If possible, you should be doing that instead.
If you have control over how handler is defined, I recommend using Boost function objects instead of function pointers.
If you HAVE to use function pointers, define handler_t with an extra void* whose value is passed along with the handler, watch out for the gotchas Martin York linked in a comment. Then you have something like this:
typedef void (*handler_t)(int foo, void *bar, void *data);
static handler_t handler_ = NULL;
static void* handler_data_ = NULL;
void set_handler(handler_t h, void *d = NULL) {
handler_ = h;
handler_data = d;
}
void handle_event(int foo, void *bar) {
if (handler_ != NULL) handler_(foo, bar, handler_data_);
}
void foo_handler(int foo, void *bar, void *data) {
Foo *fooObj = static_cast<Foo*>(data);
fooObj->handler(foo, bar);
}
// in main
set_handler(foo_handler, &some_foo_object);