Wrapping C++ class API for C consumption - c++

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?

Related

How can I expose C++ function pointers in C?

I have two types of function pointers defined in my C++ that look like this:
typedef void(*CallbackFn)(bool, std::string, py::array_t<uint8_t>&);
typedef std::function<void(std::string)> LogFunction;
Class Core{
...
void myfunc1(LogFunction lg1, CallbackFn callback, int x, std::string y);
};
and I want to be able to expose them in C but I can't seem to find a way to do so. My first try was to cast these as void* and then recast them back to their actual type. but this seems like a bad idea. So I'm clueless as how to go about this conversion.
Also the solution that I need to come-up with should be doable using C++11 at the very least.
Update:
Thank you very much for your answers. However I need to add a bit more explanation as what I'm after. I know about extern "C" and in fact the C++ functions are exposed using this already in my DLL. However, the problem I had was to pass the function pointers back and forth between the C and C++.
One way was to define function pointers in a way that can be directly usable by C. That is I needed to change for example :
typedef void(*CallbackFn)(bool, std::string, py::array_t<uint8_t>&);
typedef std::function<void(std::string)> LogFunction;
to its C compatible one :
typedef void(*CCallbackFn)(bool, char*, int, unsigned char, int length);
typedef void(*CLogFunction)(char* string, int length);
and use these instead. However, the disadvantage of doing this is that, the DLL is also used by C++ clients and this would be a hindrance to change everything C++ to be compatible by C, I'd lose the advantages of C++ by doing this.
Instead I though of coming up with a second way. The C++ stays the same, but for C linkage and interacting with other languages through C API, I do the conversion myself.
That is they use C style and then I convert this back to C++ in the implementation part. In order to further simplify this so I designed some defaults on C++ part as well. Meaning, suppose for the lack of a better example, the instance needs a callback function to log whatever happens. I define a callback function in case it was not given by the user and create two functions for C API specifically something roughly similar to this:
//in core.cpp for example
include "Core.h"
...
extern "C"
{
Core * core;
...
Core_API void* get_default_log_callback()
{
return (void*) core->SomeDefaultCallback();
}
Core_API void* set_log_callback(void* fn)
{
// convert/cast that to the c++ callback type
// CallbackFn,
core->SetCallback(fn_converted);
}
and the client could for example use the get_default_log_callback and use its return to set_log_call_back.
Basically the idea here is to be able to use the C++ already defined assets.
I was stuck at this conversion process, how to convert such callback pointers to a C compatible type ( like what I showed, it'd be really easy to just cast the pointer to void* for example and write a C wrapper that accepts void* and then recast it to the proper type.
I'd like to know about this scenario as well and whether this is a good practice or the otherwise a bad one.
Question two:
Also I'd like to know if it is possible to have a conversion from for example the CCallbackFn and CallbackFn?
Suppose I've got a function(my C function above e.g.) in a CCalbackFn form ,but I want to ultimately have it in CallbackFn form(change it and call the underlying C++ that accepts CallbackFn) ? is this possible ?
C doesn't do / cannot handle C++ name mangling (nor C++ types that are not identical to C types). You cannot use non-POD types (and plain function pointers involving types not usable in C) in anything exposed to C. And you need to use extern "C" for the exposed stuff, to disable name mangling (or rather, use whatever naming convention/mangling your current platforms C compiler uses).
In short: use extern "C" for anything that must be callable from C and make sure anything exposed that way only uses types that you can write/use in C.
You can expose a function to C by declaring it extern "C".
However, the function must only accept argument types that are valid in C.
From the look of the code above, you're going to have to express your callback in more C-like terms.
In order to expose any C++ functions to C, you should wrap the C++ calls in C functions in a plain C++ library. And export only the C functions from it. Use a common header for C functions declarations inside and outside the library. These functions will be callable from any C environment. All the C++ types wrap in a class and pass a pointer to that class across function wrappers, as a handle to C++ environment. The pointer to class should be void* or just long. And only in C++ side you will reinterpret it to own environment class.
Update 1:
You should keep C and C++ separated. It means don't do conversions between C and C++. Keep separated C versions and C++ versions of XX_log_callback functions. For instance your C++ functions uses std::string, py::array_t&. There is no way you can use it is C. No conversion available, and no way to take advantages of it in C. You can take advantage of C++ only in C++, so make a separate version for C++ only and one available for C developers.
This is a by the way. There is a technique of passing around C++ interfaces to C and back to C++. But be attentive, it uses only C compatible return and argument types. It means creating a structure with a pointer to a table of function pointers. In C++ it is an interface but in C it is a struct. This technique is used in COM/OLE2 in Windows. https://www.codeproject.com/Articles/13601/COM-in-plain-C To use such a technique you should understand very well how to make a C++ class compatible with a C struct.
Now I will just copy/paste some pieces of code from the codeproject with little explanations.
The rule of thumb when passing interfaces between C and C++, use only types compatible with C as function arguments and as return type. The first four bytes in the interface is a pointer to an array of functions, called Virtual Table:
typedef struct
{
IExampleVtbl * lpVtbl;//<-- here is the pointer to virtual table
DWORD count;//<-- here the current class data starts
char buffer[80];
} IExample;
Here you add the pointers to functions in the virtual table. The IExampleVtbl is a structure filled with pointers, and binary it is equivalent to a contiguous array of pointers
static const IExampleVtbl IExample_Vtbl = {SetString, GetString};
IExample * example;
// Allocate the class
example = (IExample *)malloc(sizeof(IExample));
example->lpVtbl = &IExample_Vtbl;//<-- here you pass the pointer to virtual functions
example->count = 1; //<-- initialize class members
example->buffer[0] = 0;
Now this is how you call the methods:
char buffer[80];
example->lpVtbl->SetString(example, "Some text");
example->lpVtbl->GetString(example, buffer, sizeof(buffer));
Keep in mind, all of above is C.
In the above example you refer explicitly the virtual table member, and also you pass it explicitly as first parameter in the functions. The C++ equivalent of call to GetString/SetString is:
example->SetString("Some text");
example->GetString(buffer, sizeof(buffer));
Here is the SetString/GetStrinf functions and the virtual table structure:
HRESULT STDMETHODCALLTYPE SetString(IExample *this, char * str)
{
memcpy(this->buffer, str, length);//be attentive, it is almost pseudocode
return(0);
}
HRESULT STDMETHODCALLTYPE GetString(IExample *this, char *buffer, int buffer_len)
{
memcpy(str, this->buffer, length);//be attentive, it is almost pseudocode
return(0);
}
typedef struct {
SetStringPtr *SetString;
GetStringPtr *GetString;
} IExampleVtbl;
The STDMETHODCALLTYPE is to make it compatible with C++ calling of member function classes, so you will be able to pass the IExample between C and C++. I believe this will be really a nightmare for the C programmers, but not an easy task for C++ counterparts.
To access that when interface is passed from C, you declare interface like this:
class IExample
{
public:
virtual HRESULT SetString(char * str) = 0;//<-- see first parameter gone away in both functions
virtual HRESULT GetString(char *buffer, int buffer_len) = 0;
};
If you implement in C++ to pass in C equivalent of above code will be:
class IExample
{
int count = 1; //<-- initialize class members
char buffer[80] = "";
public:
virtual HRESULT SetString(char * str)
{
memcpy(this->buffer, str, length);//be attentive, it is almost pseudocode
return(0);
}
virtual HRESULT GetString(char *buffer, int buffer_len)
{
memcpy(str, this->buffer, length);//be attentive, it is almost pseudocode
return(0);
}
};
One more thing. You don't use the C declaration in C++ and vice-versa. This is by the COM approach to address the issue. It might be not portable to different compilers but keep in mind, similar approach is done in the old CORBA. Only you should keep in mind. You create one interface for C and one for C++. On C++ part hide the C interface and on C hide the C++ interface. Pass around only the pointers.
I ultimately came up with my own solution which I myself refer to as "Delegating Callbacks" approach! The idea here is that, instead of directly use the C callback, you create a diversion, you create an intermediate callback that acts as a translator between the two APIs.
For example, suppose my C++ class has a method that accepts only callbacks with this signature :
typedef void(*CallbackFn)(bool, std::string, py::array_t<uint8_t>&);
And now we want to expose this to C. and this is our C callback signature :
typedef void(*CCallbackFn)(bool, const char*, unsigned char*, int rows, int cols);
Now how do we go from the first to the second one or vice versa? We create a new callback in our C++ class of type CallbackFn, and inside it execute the C callbacks. So using an indirect call, we can easily decouple the signatures between the C and C++ APIs and use the ones that are most suitable for each.
To make it more concrete we need to have something like this:
CORE_API void Core::DelegateCCallback(bool status, std::string id, py::array_t<uint8_t>& img)
{
//here is used a std::map to store my c-callbacks you can use
//vector or anything else that you like
for (auto item: this->callbackMap_c)
{
//item.first is our callback, so use it like a function
item.first(status, id.c_str(), img.mutable_data(), img.shape(0), img.shape(1));
}
}
And you update your C callback list like this, using two exposed functions, Add and Remove to add and remove any callbacks respectively :
extern "C"
{
//Core is our C++ class for example
Core* core = nullptr;
...
CORE_API void AddCallback(CCallbackFn callback)
{
core->AddCallback_C(callback);
}
CORE_API void RemoveCallback(CCallbackFn callback)
{
core->RemoveCallback_C(callback);
}
}
and back in our C++ class, AddCallback_C methods are defined like:
CORE_API void Core::AddCallback_C(CCallbackFn callback)
{
auto x = this->callbackMap_c.emplace(callback, typeid(callback).name());
}
CORE_API void Core::RemoveCallback_C(CCallbackFn callback)
{
this->callbackMap_c.erase(callback);
}
Just adding/removing the callback to the callback list. That's all.
Now when we instantiate our C++ Code, we need to add the DelegateCCallback to the callback list, so when all C++ callbacks are executed this one executes too and with it, it will loop through all the C callbacks and executes them one by one.
For example in my case, the callbacks needed to be run in a Python module, so in my constructor I had to do something like this:
CORE_API Core::Core(LogFunction logInfo)
{
//....
// add our 'Callback delegate' to the list of callbacks
// that would run.
callbackPyList.attr("append")(py::cpp_function([this](bool status, std::string id, py::array_t<uint8_t>& img)
{
this->DelegateCCallback(status, id, img);
}));
//...
}
You can get fancy with this and incorporate threads, etc as you wish.

When to put a whole C++ class framework into a DLL?

I am about to write a C++ framework that will later be used by different C++ applications. The framework will provide one main class, which will be instantiated by the application. That main class will make use of some other classes within the framework. And there will be some helper classes, to be used directly by the application.
Now I am thinking of how I should encapsulate that class framework. I could write the header and source files as usual, and then include those in the applications that will make use of the framework, so that all will be compiled in one go together with the application.
But I am not sure whether this is "the best" approach in my case. Wouldn't it be an option to put the whole framework into a DLL and then link that DLL to the applications? However, I also read that it is often not the best idea to let a DLL export whole classes, and that this approach might lead to difficulties when using STL templates as data members.
Can you recommend an approach to me, maybe something else I have not mentiond above, incl. the pros and cons of all these options?
You can create a C interface using opaque pointers, which is needed in your case because of the varying types and versions of compilers involved. Note that you may not accept or return non-C types, unless you also wrap them in opaque pointers. It's not hard, but there's a bit of work needed on your behalf.
Assuming a class 'YourClass', you would create a YourClassImpl.h and YourClassImpl.cpp (if needed) containing your C++ class code.
YourClassImpl.h
class YourClass
{
private:
int value = 12345;
public:
YourClass() {}
~YourClass() {}
int getThing() { return value; }
void setThing(int newValue) { v = newValue}
};
You would then create a YourClass.h which would be your C header file (to be included by the users of your DLL), containing an opaque pointer typedef and the declarations of your C-style interface.
YourClass.h
#ifdef MAKEDLL
# define EXPORT __declspec(dllexport) __cdecl
#else
# define EXPORT __declspec(dllimport) __cdecl
#endif
extern "C"
{
typedef struct YourClass *YC_HANDLE;
EXPORT YC_HANDLE CreateYourClass();
EXPORT void DestroyYourClass(YC_HANDLE h);
EXPORT int YourClassGetThing(YC_HANDLE h);
EXPORT void YourClassSetThing(YC_HANDLE h, int v);
}
In YourClass.cpp you would define those functions.
YourClass.cpp
#include "YourClass.h"
#include "YourClassImpl.h"
extern "C"
{
EXPORT YC_HANDLE CreateYourClass()
{
return new YourClass{};
}
EXPORT void DestroyYourClass(YC_HANDLE h)
{
delete h;
}
EXPORT int YourClassGetThing(YC_HANDLE h)
{
return h->getThing();
}
EXPORT void YourClassSetThing(YC_HANDLE h, int v)
{
h->setThing(v);
}
}
In your users code they would include YourClass.h.
TheirCode.cpp
#include "YourClass.h"
int ResetValue(int newValue)
{
YC_HANDLE h = CreateYourClass();
auto v = YourClassGetThing(h);
YourClassSetThing(h, newValue);
DestroyYourClass(h);
return v;
}
The most usual way of linking to your DLL would be with LoadLibrary/GetProcAddress - I'd also advise adding a .def file to your project to ensure that the functions are named 'nicely' and are not difficult to access because of any name decoration.
Some issues to keep an eye out for:
Only the standard C fundamental types can be passed back and forth across the interface. Don't use any C++ specific types or classes.
PODs and arrays of PODs may be safe for you to use, but watch out for any packing or alignment issues.
Exceptions must not cross the interface boundaries - catch anything that gets thrown and convert it to a return code or equivalent.
Ensure that memory allocated on either side of the boundary is deallocated on the same side.

How do I use google mock in C?

I'm maintaining a legacy project written in C and it's unfeasible to get it running with a C++ compiler. Since the code is cross compiled it is however possible to run unit-tests or similar in a host environment. hence it's also possible to interface with a C++ host compiler and use google-test and google-mock.
There are certain capabilities of google-mock which seem to be very tempting to be used for testing as invoking real implementations and setting call expectations.
I would like to be able to use them in C code. I can see that it is indeed possible to use google-mock without using vtables, but it requires templates.
Is there a way to mock bare C functions with google mock?
EDIT:
I basically had to use google mock, I assume though that everybody else who will read this thread has better flexibility than me.
I found a way to be able to mock bare C functions in google-mock.
The solution is to declare foobar to be a weak alias that maps to foobarImpl. In production code you do not implement foobar() and for unit tests you provide an implementation that calls a static mock object.
This solution is GCC specific but there are other compilers/linkers that provide weak aliasing.
rename the function void foobar(); to void foobarImpl();
add an attribute to the function foobar like: void foobar() __attribute__((weak, alias("foobarImpl") ));
if you want to have a non weak alias use a preproessor directive to remove the weak from the attributes.
Hence:
#pragma once
void foobar();
becomes
// header.h
#pragma once
void foobar();
void foobarImpl(); // real implementation
and
extern "C" {
#include "header.h"
}
// code.c
void foobarImpl() {
/* do sth */
}
void foobar() __attribute__(( weak, alias ("foobarImpl") )); // declare foobar to be a weak alias of foobarImpl
This will tell the gnu linker to link calls of foobar() with foobarImpl() whenever there is no symbol called foobar()
then add the testing code
struct FooInterface {
virtual ~FooInterface() {}
virtual void invokeFoo() const { }
};
class MockFoo : public FooInterface {
public:
MOCK_CONST_METHOD0(invokeFoo, void());
}
struct RealFoo : public FooInterface {
virtual ~RealFoo() {}
virtual void invokeFoo() const { foobarImpl(); }
};
MockFoo mockFoo;
RealFoo realFoo;
void foobar() {
mockFoo.invokeFoo();
}
if this code is compiled and linked it will replace foobar with the mock call.
if you really want to call foobar() you can still do add a default invocation.
ON_CALL(mockFoo, invokeFoo())
.WillByDefault(Invoke(&realFoo,&RealFoo::invokeFoo));
As from the Google Mock FAQ:
My code calls a static/global function. Can I mock it?
You can, but you need to make some changes.
In general, if you find yourself needing to mock a static function, it's a sign that your modules are too tightly coupled (and less flexible, less reusable, less testable, etc). You are probably better off defining a small interface and call the function through that interface, which then can be easily mocked. It's a bit of work initially, but usually pays for itself quickly.
This Google Testing Blog post says it excellently. Check it out.
Your question specifically mentions Google Mock, but then does not state any other reason for using that framework. The other answer suggests using a workaround which seems unnecessarily intrusive.
Hence I hope I am allowed to make an alternative suggestion which works well without having to use weak aliases etc.
I have used CppUTest (https://cpputest.github.io/) for unit test with mock, successfully on a couple of large mainly-C projects (some C++).
The mocking works without having to resort to any subterfuge of the above sort.
Unfortunately the project documentation is a little weak, some better (if a little agile-doctrinaire) information and examples in the book (also seen circulating as a PDF) "Test Driven Development for Embedded C" - James W Greening (ISBN-13: 978-1-934356-62-3)
I realize this is a super old thread, but I'm hoping I can make someone's life a little easier if and when they come across this question.
You can very easily autogenerate mocks for C functions that are compatible with GoogleTest using Mimicc. Find whatever header files declare the functions you want to mock, "compile" them into mock implementation object files, and link them into your test binary including definitions of the mock_fatal() and mock_failure() functions as described in the User Guide specifically for Google Test. You'll have to use the Mimicc API for interacting with the Mimicc-generated mocks (i.e. it doesn't use GoogleMock's API for setting expectations, etc.), but they can comfortably live alongside the GoogleMock-generated mocks.
To be more concrete, suppose you have a C header file foo.h which declares a few functions you want to mock. For example:
/*!
* #param[out] pBuf Destination buffer to read to
* #param[in] sz Size of the read buffer
*/
int magic_read(char *pBuf, const size_t sz);
/*!
* #param[in] pBuf Source buffer to write from
* #param[in] sz Size of the write buffer
*/
int magic_write(const char *pBuf, const size_t sz);
You can create mocks for these by compiling foo.h with all the same CFLAGS that would be used to compile the accompanying production foo.c :
prompt$ mimicc -c foo.h -o mock.o --hout=foo-mock.h -DSOME_PREPROC=1 -I <your includes>
To use this in a test, set expectations and returns using the API declared in foo-mock.h as shown on the command line invocation above. Include the implementation of mock_fatal() and mock_failure() for Google Test.
#include <gtest/gtest.h>
#include <memory>
std::unique_ptr<char []> mockErrStr(const char *pLocation, unsigned count, const char *pMsg)
{
const char *pFmtStr = "mock assertion failure! location: '%s',"
" iteration: %d, message: %s";
size_t n = snprintf(NULL, 0, pFmtStr, pLocation, count, pMsg);
std::unique_ptr<char []> outStrBuf(new char[n+1]);
snprintf(outStrBuf.get(), n+1, pFmtStr, pLocation, count, pMsg);
return outStrBuf;
}
void mock_failure(const char *pLocation, unsigned count, const char *pMsg)
{
ADD_FAILURE() << mockErrStr(pLocation, count, pMsg).get();
}
void mock_fatal(const char *pLocation, unsigned count, const char *pMsg)
{
FAIL() << mockErrStr(pLocation, count, pMsg).get();
exit(1);
}
TEST_F(MimiccPoC, test1)
{
char mock_ret_data[] = "HELLO WORLD";
MOCK_FUNCTIONS(foo).magic_read.expect(32);
MOCK_FUNCTIONS(foo).magic_read.andReturn(
1, mock_ret_data, sizeof(mock_ret_data));
char testRetBuf[32];
int testRes = magic_read(testRetBuf, sizeof(testRetBuf));
ASSERT_EQ(1, testRes);
ASSERT_STREQ(testRetBuf, "HELLO WORLD");
}
While this may seem like a lot, once the plumbing is set up, you can automatically mock any C or C++ code you have without actually having to write or maintain additional mock code, you just focus on the tests. Quite a bit easier in the long run.

Nested Classes C++ static inner methods (Xml parsing and trying to populate vector with values)

So this is what I am trying to accomplish. I am trying to use a sax parser to parse some XML. it looks like I need to call all their methods as statics. So if I want to pass a value back from say startElement it is static void startElement. Which brings me to my example code. I have been pulling my hair on how to update a value in a Nesting class from a static member function.
I have looked at several things such as defining OuterClass * oc; then trying to reference oc->allRecords, but since it is a static method inside, it fails. I am sure I am doing something wrong architecturally, so any feedback on what would be the right way to do this would be a great help. Thanks.
class Attribute {
string AttributeName;
string AttributeValue;
};
typedef shared_ptr<Attribute> AttributePtr;
class AttributeSet {
vector<AttributePtr> Attributes;
};
typedef shared_ptr<AttributeSet> AttributeSetPtr;
class OuterClass {
public :
vector<AttributeSetPtr> allRecords;
class InnerClass {
public:
static mymethod1() {
// I need to be able to set attributes here :
// This would be the characters method for sax parsing
// What is the right way to Attributes.push_back(new Attribute(Name,Value));
}
static mymethod2() {
// I also need to be able to add Records here :
// This would be the endElement for sax parsing
// What is the right way to allRecords.push_back(AttributeSet);
}
};
// EDIT: CALLING CODE GOES HERE (WAS EDITED - SEE BELOW)
};
// ADDING INFORMATION REGARDING HOW METHOD 1 & 2 are called
xmlSAXHandler saxHandler;
memset(&saxHandler, 0, sizeof(saxHandler));
saxHandler.initialized = XML_SAX2_MAGIC;
...
saxHandler.endElementsNs = &InnerClass::method2;
saxHandler.characters = &InnerClass::method1;
...
InnerClass innerXmlParsingClass
xmlSaxUserParseMemory( &saxHandler, &innerXmlParsingClass, xmlString, xmlString.length());
Your mistake is using an inner class (are you coming from Java?).
I don't know what you believe you are are achieving with an inner class, but it won't work. Don't use inner classes in C++ unless you really know what it does (for inner classes, protected and private members of the outer classes are seen as if they were public).
Now, as the solution to your problem, I guess it depends on the implementation you're using (I used once Apache's Xerces SAX, but I know Microsoft offers its own SAX implementation, and that there should be a lot other alternatives, so...)
Edit
After the comment, I found the following tutorial:
http://www.jamesh.id.au/articles/libxml-sax/libxml-sax.html
I must say that, coming from Java to C++, and using a C API, you have a kind of courage...
:-D
If you are not familiar enough with function pointers, and C in general, using libxml2 will be a challenge. Be sure that in the end, you will understand those notions... Note that C have a way to handle the data that C++, Java or C# developers associate to this. The C way is to pass a pointer to your data (the user data) to a function, and when the callback is called, it passes back this pointer, typed as a void *. You must then cast it back to its right type, and voilà, you have your this back.
:-)
Anyway, reading the doc, I see that when you parse the file, you'll call the following C function:
int xmlSAXUserParseFile( xmlSAXHandlerPtr sax,
void * user_data,
const char * filename);
the user_data part is the one that interest you because it enables you to have a context. So, wrapping this function in a C++ class, you could have something like:
// MySaxBase.hpp
class MySaxBase
{
public :
MySaxBase() ;
int parseFile(const std::string & p_filename) ;
virtual void startDocument() ;
virtual void endDocument() ;
private :
static void do_startDocument(void *p_user_data) ;
static void do_endDocument(void *p_user_data) ;
xmlSAXHandler m_sax ;
}
.
// MySaxBase.cpp
extern "C"
{
void do_startDocument(void *p_user_data)
{
// this static method will convert the p_user_data into
// the this pointer...
MySaxBase * saxBase = static_cast<MySaxBase *>(p_user_data) ;
// ...and call the right virtual method
saxBase->startDocument() ;
}
void do_endDocument(void *p_user_data)
{
// this static method will convert the p_user_data into
// the this pointer...
MySaxBase * saxBase = static_cast<MySaxBase *>(p_user_data) ;
// ...and call the right virtual method
saxBase->endDocument() ;
}
} // extern "C"
MySaxBase::MySaxBase()
{
// the m_sax structure must be set to zero to NULL all its
// pointers to functions
memset(&m_sax, 0, sizeof(xmlSAXHandler)) ;
// Now, we initialize some pointers to the static method we
// want to be called
this->m_sax.startDocument = do_startDocument ;
this->m_sax.endDocument = do_endDocument ;
}
int MySaxBase::parseFile(const std::string & p_filename)
{
// the important thing, here, is the this pointer, passed as
// a user_data parameter
return xmlSAXUserParseFile(&m_sax, this, p_filename.c_str()) ;
}
void MySaxBase::startDocument()
{
// The document started. Override this method to
// actually do something
}
void MySaxBase::endDocument()
{
// The document ended. Override this method to
// actually do something
}
I did not test this, and I never used libxml2, but I guess the code must be Ok, and this should be enough for you to continue on your own: Just add the methods you want to support, initialize the sax handler with the relevant function pointers, and you'll have your class complete.
The MySaxBase::startDocument and MySaxBase::endDocument methods are virtual just for you to derive from MySaxBase and then override those methods.
Edit 2
I'll reproduce here Steve Jessop's excellent comment:
+1. One tiny quibble - I don't think that static member functions are guaranteed by the C++ standard to have C linkage / calling convention, but to use them as a callback from a C API, that's what they need. I don't specifically know what implementations it makes a difference, but for safety do_startDocument should be a free function declared with extern "C". On the same subject: a Java programmer may not realise you have make sure that the function can't throw an exception (because C doesn't have them). So you'd normally want to see a try/catch(...) in the wrapper function. – Steve Jessop
Following this, and after reading Johannes Schaub - litb (who else?) no less excellent answer at static vs extern "C"/"C++" , I modified the code to make do_startDocument and do_endDocument real C functions (i.e. wrapped in an extern "C" block). This usually is not important (I never encountered this kind of problem), but, better safe than sorry.
Your basic problem is that static methods are not per-instance, so there is no this pointer. You somehow need to get a OuterClass* passed to mymethod1 and mymethod2.
If you show us how mymethod1 and mymethod2 are called, we can help you further.
If it's simply called by you someplace where you have a OuterClass object, then your solution is simple:
class OuterClass
{
// ...
static void mymethod1(OuterClass* oc)
{
oc->all_records.push_back( something );
}
};
void some_func()
{
OuterClass oc;
OuterClass::method1(&oc);
}
Since you updated your question here is how you should do this:
class OuterClass {
public:
vector<AttributeSetPtr> allRecords;
void characters(const xmlChar* ch, int len)
{
// do here whatever you want
allRecords.push_back(bla bla);
}
static void static_characters(void* ctx, const xmlChar* ch, int len) {
// retrieve this pointer from ctx
static_cast<OuterClass*>(ctx)->characters(ch, len);
}
};
saxHandler.characters = &OuterClass::static_characters;
...
OuterClass outerClass;
xmlSaxUserParseMemory(&saxHandler, static_cast<void*>(&outerClass), xmlString, xmlString.length());

Writing a C++ wrapper for a C library

I have a legacy C library, written in an OO type form. Typical functions are like:
LIB *lib_new();
void lib_free(LIB *lib);
int lib_add_option(LIB *lib, int flags);
void lib_change_name(LIB *lib, char *name);
I'd like to use this library in my C++ program, so I'm thinking a C++ wrapper is required.
The above would all seem to map to something like:
class LIB
{
public:
LIB();
~LIB();
int add_option(int flags);
void change_name(char *name);
...
};
I've never written a C++ wrapper round C before, and can't find much advice about it. Is this a good/typical/sensible approach to creating a C++/C wrapper?
A C++ wrapper is not required - you can simply call the C functions from your C++ code. IMHO, it's best not to wrap C code - if you want to turn it into C++ code - fine, but do a complete re-write.
Practically, assuming your C functions are declared in a file called myfuncs.h then in your C++ code you will want to include them like this:
extern "C" {
#include "myfuncs.h"
}
in order to give them C linkage when compiled with the C++ compiler.
I usually only write a simple RAII wrapper instead of wrapping each member function:
class Database: boost::noncopyable {
public:
Database(): handle(db_construct()) {
if (!handle) throw std::runtime_error("...");
}
~Database() { db_destruct(handle); }
operator db_t*() { return handle; }
private:
db_t* handle;
};
With the type conversion operator this can be used with the C functions:
Database db;
db_access(db, ...); // Calling a C function with db's type conversion operator
I think it only makes sense to write a wrapper if it makes the use of the library simpler. In your case, you're making it unnecessary to pass a LIB* around, and presumably it will be possible to create LIB objects on the stack, so I'd say this is an improvement.
That's generally how I would approach it. I would also not use char* but use std::string.
A C++ wrapper is not needed per se. There's nothing stopping you from calling the C functions in your code.
I'd also look at renaming LIB to something a bit better, if nothing else "Lib"
Change Name is likely to be a getter setter...
so GetName(char *) SetName(char *)
and then look at changing it to std::string instead of char*, if its SetName(const std::string name) it will accept a char* as a parameter.
ie, slowly move to C++isms
Assuming that the C library's allocation/deallocation instances are create_instance and destroy_instance, and it exposes a function called call_function, and it does not provide an API for deep copying instances, this will work:
class Wrapper
{
public:
Wrapper(): m_instance(create_instance(), destroy_instance) {}
explicit operator bool() const
{
// null check
return bool(m_instance);
}
void callFunction()
{
call_function(m_instance.get());
}
private:
std::unique_ptr<instance, decltype(&destroy_instance)> m_instance;
};