Cpp2C: An extern C wrapper code generator for C++

A Template-Based Example

Suppose we have the following input file at: C:\Projects\Test\Test.hpp

(Input File:) test.hpp

#include <vector>

template class std::vector<int>;      // (I)

int func(std::vector<int> v);

Usage

Under Windows, we type

C:\Projects\Test\Test.hpp -g "C:\Program Files\gccxml 0.9\bin" -t msvc9 --nothrow

Output File

#include "Test.hpp"

#include "Test_C_Wrapper.h"

// (1)

#ifdef WIN32
#include <Windows.h>
extern "C" BOOL WINAPI DllMain(
    HINSTANCE hinstDLL,  // handle to DLL module
    DWORD fdwReason,     // reason for calling function
    LPVOID lpReserved )  // reserved
{
    // Perform actions based on the reason for calling.
    switch( fdwReason )
    {
        case DLL_PROCESS_ATTACH:
         // Initialize once for each new process.
         // Return FALSE to fail DLL load.
            break;

        case DLL_THREAD_ATTACH:
         // Do thread-specific initialization.
            break;

        case DLL_THREAD_DETACH:
         // Do thread-specific cleanup.
            break;

        case DLL_PROCESS_DETACH:
         // Perform any necessary cleanup.
            break;
    }
    return TRUE;  // Successful DLL_PROCESS_ATTACH.
}
#endif  // WIN32


// (2)

PTR_std_string std_string_string() {

        return (PTR_std_string)new (std::nothrow) ::std::string;

}

PTR_std_string std_string_string_array(size_t arr_size) {

        return (PTR_std_string)new (std::nothrow) ::std::string[arr_size];

}

void std_string_delete_string(PTR_std_string class_this) {

        delete ((::std::string*)class_this);

}

void std_string_delete_string_array(PTR_std_string class_this) {

        delete []((::std::string*)class_this);

}

char const * std_string_c_str_const(const PTR_std_string class_this) {

        return ((const ::std::string*) class_this)->::std::string::c_str();

}


// (3)

int func(PTR_std_vector_int_std_allocator_int__ v) {

        return ::func(*(::std::vector<int, std::allocator<int> >*)v);

}


// (4)

PTR_std_vector_int_std_allocator_int__ std_vector_int_std_allocator_int___vector() {

        return (PTR_std_vector_int_std_allocator_int__)new (std::nothrow) ::std::vector<int, std::allocator<int> >;

}

PTR_std_vector_int_std_allocator_int__ std_vector_int_std_allocator_int___vector2(const PTR_std_allocator_int_ _Al) {

        return (PTR_std_vector_int_std_allocator_int__)new (std::nothrow) ::std::vector<int, std::allocator<int> >(*(const ::std::allocator<int>*)_Al);

}

PTR_std_vector_int_std_allocator_int__ std_vector_int_std_allocator_int___vector3(size_t _Count) {

        return (PTR_std_vector_int_std_allocator_int__)new (std::nothrow) ::std::vector<int, std::allocator<int> >(_Count);

}

PTR_std_vector_int_std_allocator_int__ std_vector_int_std_allocator_int___vector4(size_t _Count, int const* const _Val) {

        return (PTR_std_vector_int_std_allocator_int__)new (std::nothrow) ::std::vector<int, std::allocator<int> >(_Count, *_Val);

}

PTR_std_vector_int_std_allocator_int__ std_vector_int_std_allocator_int___vector5(size_t _Count, int const* const _Val, const PTR_std_allocator_int_ _Al) {

        return (PTR_std_vector_int_std_allocator_int__)new (std::nothrow) ::std::vector<int, std::allocator<int> >(_Count, *_Val, *(const ::std::allocator<int>*)_Al);

}

PTR_std_vector_int_std_allocator_int__ std_vector_int_std_allocator_int___vector6(const PTR_std_vector_int_std_allocator_int__ _Right) {

        return (PTR_std_vector_int_std_allocator_int__)new (std::nothrow) ::std::vector<int, std::allocator<int> >(*(const ::std::vector<int, std::allocator<int> >*)_Right);

}

void std_vector_int_std_allocator_int___delete_vector(PTR_std_vector_int_std_allocator_int__ class_this) {

        delete ((::std::vector<int, std::allocator<int> >*)class_this);

}

PTR_std_vector_int_std_allocator_int__ std_vector_int_std_allocator_int___vector_array(size_t arr_size) {

        return (PTR_std_vector_int_std_allocator_int__)new (std::nothrow) ::std::vector<int, std::allocator<int> >[arr_size];

}

void std_vector_int_std_allocator_int___delete_vector_array(PTR_std_vector_int_std_allocator_int__ class_this) {

        delete []((::std::vector<int, std::allocator<int> >*)class_this);

}

void std_vector_int_std_allocator_int____Construct_n(PTR_std_vector_int_std_allocator_int__ class_this, size_t _Count, int const* const _Val) {

        ((::std::vector<int, std::allocator<int> >*) class_this)->::std::vector<int, std::allocator<int> >::_Construct_n(_Count, *_Val);

}

void std_vector_int_std_allocator_int___reserve(PTR_std_vector_int_std_allocator_int__ class_this, size_t _Count) {

        ((::std::vector<int, std::allocator<int> >*) class_this)->::std::vector<int, std::allocator<int> >::reserve(_Count);

}

size_t std_vector_int_std_allocator_int___capacity_const(const PTR_std_vector_int_std_allocator_int__ class_this) {

        return ((const ::std::vector<int, std::allocator<int> >*) class_this)->::std::vector<int, std::allocator<int> >::capacity();

}

void std_vector_int_std_allocator_int___resize(PTR_std_vector_int_std_allocator_int__ class_this, size_t _Newsize) {

        ((::std::vector<int, std::allocator<int> >*) class_this)->::std::vector<int, std::allocator<int> >::resize(_Newsize);

}

void std_vector_int_std_allocator_int___resize2(PTR_std_vector_int_std_allocator_int__ class_this, size_t _Newsize, int _Val) {

        ((::std::vector<int, std::allocator<int> >*) class_this)->::std::vector<int, std::allocator<int> >::resize(_Newsize, _Val);

}

size_t std_vector_int_std_allocator_int___size_const(const PTR_std_vector_int_std_allocator_int__ class_this) {

        return ((const ::std::vector<int, std::allocator<int> >*) class_this)->::std::vector<int, std::allocator<int> >::size();

}

size_t std_vector_int_std_allocator_int___max_size_const(const PTR_std_vector_int_std_allocator_int__ class_this) {

        return ((const ::std::vector<int, std::allocator<int> >*) class_this)->::std::vector<int, std::allocator<int> >::max_size();

}

BOOL_C std_vector_int_std_allocator_int___empty_const(const PTR_std_vector_int_std_allocator_int__ class_this) {

        return (BOOL_C)((const ::std::vector<int, std::allocator<int> >*) class_this)->::std::vector<int, std::allocator<int> >::empty();

}

PTR_std_allocator_int_ std_vector_int_std_allocator_int___get_allocator_const(const PTR_std_vector_int_std_allocator_int__ class_this) {

        return (PTR_std_allocator_int_)new (std::nothrow) ::std::allocator<int>(((const ::std::vector<int, std::allocator<int> >*) class_this)->::std::vector<int, std::allocator<int> >::get_allocator());

}

int const* const std_vector_int_std_allocator_int___at_const(const PTR_std_vector_int_std_allocator_int__ class_this, size_t _Pos) {

        return &((const ::std::vector<int, std::allocator<int> >*) class_this)->::std::vector<int, std::allocator<int> >::at(_Pos);

}

int* const std_vector_int_std_allocator_int___at(PTR_std_vector_int_std_allocator_int__ class_this, size_t _Pos) {

        return &((::std::vector<int, std::allocator<int> >*) class_this)->::std::vector<int, std::allocator<int> >::at(_Pos);

}

int* const std_vector_int_std_allocator_int___front(PTR_std_vector_int_std_allocator_int__ class_this) {

        return &((::std::vector<int, std::allocator<int> >*) class_this)->::std::vector<int, std::allocator<int> >::front();

}

int const* const std_vector_int_std_allocator_int___front_const(const PTR_std_vector_int_std_allocator_int__ class_this) {

        return &((const ::std::vector<int, std::allocator<int> >*) class_this)->::std::vector<int, std::allocator<int> >::front();

}

int* const std_vector_int_std_allocator_int___back(PTR_std_vector_int_std_allocator_int__ class_this) {

        return &((::std::vector<int, std::allocator<int> >*) class_this)->::std::vector<int, std::allocator<int> >::back();

}

int const* const std_vector_int_std_allocator_int___back_const(const PTR_std_vector_int_std_allocator_int__ class_this) {

        return &((const ::std::vector<int, std::allocator<int> >*) class_this)->::std::vector<int, std::allocator<int> >::back();

}

void std_vector_int_std_allocator_int___push_back(PTR_std_vector_int_std_allocator_int__ class_this, int const* const _Val) {

        ((::std::vector<int, std::allocator<int> >*) class_this)->::std::vector<int, std::allocator<int> >::push_back(*_Val);

}

void std_vector_int_std_allocator_int___pop_back(PTR_std_vector_int_std_allocator_int__ class_this) {

        ((::std::vector<int, std::allocator<int> >*) class_this)->::std::vector<int, std::allocator<int> >::pop_back();

}

void std_vector_int_std_allocator_int___assign(PTR_std_vector_int_std_allocator_int__ class_this, size_t _Count, int const* const _Val) {

        ((::std::vector<int, std::allocator<int> >*) class_this)->::std::vector<int, std::allocator<int> >::assign(_Count, *_Val);

}

void std_vector_int_std_allocator_int____Reverse(PTR_std_vector_int_std_allocator_int__ class_this, int * _First, int * _Last) {

        ((::std::vector<int, std::allocator<int> >*) class_this)->::std::vector<int, std::allocator<int> >::_Reverse(_First, _Last);

}

void std_vector_int_std_allocator_int___clear(PTR_std_vector_int_std_allocator_int__ class_this) {

        ((::std::vector<int, std::allocator<int> >*) class_this)->::std::vector<int, std::allocator<int> >::clear();

}

void std_vector_int_std_allocator_int___swap(PTR_std_vector_int_std_allocator_int__ class_this, PTR_std_vector_int_std_allocator_int__ _Right) {

        ((::std::vector<int, std::allocator<int> >*) class_this)->::std::vector<int, std::allocator<int> >::swap(*(::std::vector<int, std::allocator<int> >*)_Right);

}

PTR_std_vector_int_std_allocator_int__ std_vector_int_std_allocator_int___operator_assign(PTR_std_vector_int_std_allocator_int__ class_this, const PTR_std_vector_int_std_allocator_int__ _Right) {

        return (PTR_std_vector_int_std_allocator_int__)new (std::nothrow) ::std::vector<int, std::allocator<int> >(((::std::vector<int, std::allocator<int> >*) class_this)->::std::vector<int, std::allocator<int> >::operator=(*(const ::std::vector<int, std::allocator<int> >*)_Right));

}

int const* const std_vector_int_std_allocator_int___operator_subscript_const(const PTR_std_vector_int_std_allocator_int__ class_this, size_t _Pos) {

        return &((const ::std::vector<int, std::allocator<int> >*) class_this)->::std::vector<int, std::allocator<int> >::operator[](_Pos);

}

int* const std_vector_int_std_allocator_int___operator_subscript(PTR_std_vector_int_std_allocator_int__ class_this, size_t _Pos) {

        return &((::std::vector<int, std::allocator<int> >*) class_this)->::std::vector<int, std::allocator<int> >::operator[](_Pos);

}

PTR_std_allocator_int__rebind_int_ std_allocator_int__rebind_int__rebind(const PTR_std_allocator_int__rebind_int_ arg0) {

        return (PTR_std_allocator_int__rebind_int_)new (std::nothrow) ::std::allocator<int>::rebind<int>(*(const ::std::allocator<int>::rebind<int>*)arg0);

}

PTR_std_allocator_int__rebind_int_ std_allocator_int__rebind_int__rebind2() {

        return (PTR_std_allocator_int__rebind_int_)new (std::nothrow) ::std::allocator<int>::rebind<int>;

}

PTR_std_allocator_int_ std_allocator_int__allocator() {

        return (PTR_std_allocator_int_)new (std::nothrow) ::std::allocator<int>;

}

PTR_std_allocator_int_ std_allocator_int__allocator2(const PTR_std_allocator_int_ arg0) {

        return (PTR_std_allocator_int_)new (std::nothrow) ::std::allocator<int>(*(const ::std::allocator<int>*)arg0);

}

void std_allocator_int__delete_allocator(PTR_std_allocator_int_ class_this) {

        delete ((::std::allocator<int>*)class_this);

}

PTR_std_allocator_int_ std_allocator_int__allocator_array(size_t arr_size) {

        return (PTR_std_allocator_int_)new (std::nothrow) ::std::allocator<int>[arr_size];

}

void std_allocator_int__delete_allocator_array(PTR_std_allocator_int_ class_this) {

        delete []((::std::allocator<int>*)class_this);

}

int * std_allocator_int__address_const(const PTR_std_allocator_int_ class_this, int* const _Val) {

        return ((const ::std::allocator<int>*) class_this)->::std::allocator<int>::address(*_Val);

}

int const * std_allocator_int__address_const2(const PTR_std_allocator_int_ class_this, int const* const _Val) {

        return ((const ::std::allocator<int>*) class_this)->::std::allocator<int>::address(*_Val);

}

void std_allocator_int__deallocate(PTR_std_allocator_int_ class_this, int * _Ptr, size_t arg1) {

        ((::std::allocator<int>*) class_this)->::std::allocator<int>::deallocate(_Ptr, arg1);

}

int * std_allocator_int__allocate(PTR_std_allocator_int_ class_this, size_t _Count) {

        return ((::std::allocator<int>*) class_this)->::std::allocator<int>::allocate(_Count);

}

int * std_allocator_int__allocate2(PTR_std_allocator_int_ class_this, size_t _Count, void const * arg1) {

        return ((::std::allocator<int>*) class_this)->::std::allocator<int>::allocate(_Count, arg1);

}

void std_allocator_int__construct(PTR_std_allocator_int_ class_this, int * _Ptr, int const* const _Val) {

        ((::std::allocator<int>*) class_this)->::std::allocator<int>::construct(_Ptr, *_Val);

}

void std_allocator_int__destroy(PTR_std_allocator_int_ class_this, int * _Ptr) {

        ((::std::allocator<int>*) class_this)->::std::allocator<int>::destroy(_Ptr);

}

size_t std_allocator_int__max_size_const(const PTR_std_allocator_int_ class_this) {

        return ((const ::std::allocator<int>*) class_this)->::std::allocator<int>::max_size();

}

PTR_std_allocator_int__rebind_int_ std_allocator_int__rebind_int__operator_assign(PTR_std_allocator_int__rebind_int_ class_this, const PTR_std_allocator_int__rebind_int_ arg0) {

        return (PTR_std_allocator_int__rebind_int_)new (std::nothrow) ::std::allocator<int>::rebind<int>(((::std::allocator<int>::rebind<int>*) class_this)->::std::allocator<int>::rebind<int>::operator=(*(const ::std::allocator<int>::rebind<int>*)arg0));

}

PTR_std_allocator_int_ std_allocator_int__operator_assign(PTR_std_allocator_int_ class_this, const PTR_std_allocator_int_ arg0) {

        return (PTR_std_allocator_int_)new (std::nothrow) ::std::allocator<int>(((::std::allocator<int>*) class_this)->::std::allocator<int>::operator=(*(const ::std::allocator<int>*)arg0));

}

PTR_std_allocator_int__rebind_int_ std_allocator_int__rebind_int__rebind3(const PTR_std_allocator_int__rebind_int_ arg0) {

        return (PTR_std_allocator_int__rebind_int_)new (std::nothrow) ::std::allocator<int>::rebind<int>(*(const ::std::allocator<int>::rebind<int>*)arg0);

}

PTR_std_allocator_int__rebind_int_ std_allocator_int__rebind_int__rebind4() {

        return (PTR_std_allocator_int__rebind_int_)new (std::nothrow) ::std::allocator<int>::rebind<int>;

}

void std_allocator_int__rebind_int__delete_rebind(PTR_std_allocator_int__rebind_int_ class_this) {

        delete ((::std::allocator<int>::rebind<int>*)class_this);

}

PTR_std_allocator_int__rebind_int_ std_allocator_int__rebind_int__rebind_array(size_t arr_size) {

        return (PTR_std_allocator_int__rebind_int_)new (std::nothrow) ::std::allocator<int>::rebind<int>[arr_size];

}

void std_allocator_int__rebind_int__delete_rebind_array(PTR_std_allocator_int__rebind_int_ class_this) {

        delete []((::std::allocator<int>::rebind<int>*)class_this);

}

PTR_std_allocator_int__rebind_int_ std_allocator_int__rebind_int__operator_assign2(PTR_std_allocator_int__rebind_int_ class_this, const PTR_std_allocator_int__rebind_int_ arg0) {

        return (PTR_std_allocator_int__rebind_int_)new (std::nothrow) ::std::allocator<int>::rebind<int>(((::std::allocator<int>::rebind<int>*) class_this)->::std::allocator<int>::rebind<int>::operator=(*(const ::std::allocator<int>::rebind<int>*)arg0));

}

Output Explanation and relevant command-line flags

The output contains 3 code segments:

  1. Like in the simple example, the DllMain() code for Windows is auto-generated.
  2. Since std::string appears in the header files, it's code is being auto-generated. Since std::string is a very common interface class - not all functions are being wrapped: only the basic constructors, destructors and the c_str() method. You can auto-generate all the std::string method (the same as done for vector<int>) by using the --string flag in the command line.
  3. func() code is auto-generated. A new type is being created for vector<int>, defined at test_C_Wrapper.h.
  4. Since func() (at (3) is using the vector<int> type - its code is also auto-generated. The PTR_std_vector_int_std_allocator_int__ type is an opaque pointer to the std::vector<int, std::allocator<int>> C++ class. Notice that the code is auto-generated recursively: after vector<int> is auto-generated - all the types it dependent on are also being auto-generated. Notice that you need to explicitly declare the template (at (I), the second line of the input file), to make sure the the template instantiation would be created - and its code would be auto-generated. Otherwise - compiler optimizations might suppress it.
Notice that since we've used the --nothrow flag - no exception handling code is being auto-generated.

Recent Forum Posts

No recent posts

Recent Blog Entries

No recent entries