One way to create C++ 'wrappers' for structures defined in a C library, so that you can easily pass pointers to API calls in such a library is to emulate the way the MFC (Microsoft Foundation Class) library wraps GDI objects, such as the RECT
structure, into classes like CRect
.
MFC uses straightforward inheritance of the 'base' structure, and provides operators in each class that return pointers to the base structure (which will actually be a class instance's this
pointer).
In the code below, I show the definition of the RECT
structure and some excerpts of the CRect
class, from the relevant Windows headers and MFC headers/source.
// The "C" base structure, from "windef.h"
typedef struct tagRECT
{
LONG left;
LONG top;
LONG right;
LONG bottom;
} RECT, *LPRECT;
typedef const RECT *LPCRECT;
class CRect : public tagRECT
{
public:
CRect(int l, int t, int r, int b) {
// Assign given parameters to base structure members...
left = l; top = t; right = r; bottom = b;
}
//...
// Utility routines...
int Width() const {
return right - left;
}
//...
// convert between CRect and LPRECT/LPCRECT (no need for &)
operator LPRECT() {
return this;
}
operator LPCRECT() const {
return this;
}
//...
};
With wrapper classes defined like this, you can pass a CRect
object (as in the comment above, no need for &
) to a call from your C Library that expects a pointer to a RECT
. For example, the GetWindowRect()
function takes an LPRECT
parameter and is called, from C, like this:
HWND hWnd;
RECT rect;
BOOL answer = GetWindowRect(hWnd, &rect); // Pass pointer to C structure
Using the CRect
class, you can just pass the object, and the LPRECT
operator will take care of the rest (but you can add the &
if you really want to):
HWND hWnd;
CRect rc;
BOOL answer = GetWindowRect(hWnd, rc);
There are limitations and caveats involved in this approach (e.g. horrid things may happen if the C library expects a RECT
to be passed by value), but it may be an approach you find helpful.