How to use C++ Classes in C

How to use C++ classes in C source code.
I want to declare a C++ object in C source code and
call its method.
Please advise.

Thanks,
Subbarao
If the C++ type is not a PODType, http://en.cppreference.com/w/cpp/concept/PODType
it would have to be exposed to C clients via an opaque pointer.

For example:

header
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
#ifndef A_H_INCLUDED
#define A_H_INCLUDED

#ifdef __cplusplus
    extern "C"
    {
#endif // __cplusplus

        //////////// interface for C clients //////////////////////

        typedef struct A A ;

        A* construct_A( const char* name, int value ) ;
        void destroy_A( A* pa ) ;
        A* copy_construct_A( const A* pa ) ;
        A* assign_A( A* This, const A* that ) ; // c-style: dest, srce

        const char* name_A( const A* This ) ;
        void rename_A( A* This, const char* new_name ) ;
        int value_A( const A* This ) ;
        void revalue_A( A* This, int new_value ) ;

        ////////////////////////////////////////////////////////////

#ifdef __cplusplus
}
#endif // __cplusplus

////////////////////////////////////////////////

#ifdef __cplusplus

    ////////////// this is C++ ////////////////////////

    // note: the C++ class may be in a separate header of its own
    struct A // not a standard layout type
    {
        std::string name_ ;
        int value_ ;

        A( std::string name, int value ) : name_( std::move(name) ), value_(value) {}

        const std::string& name() const { return name_ ; }
        void rename( std::string new_name ) { name_ = std::move(new_name) ; }

        int value() const { return value_ ; }
        void revalue( int new_value ) { value_ = new_value ; }
    };

    extern "C" // inlined here for brevity; typically placed in a separate .cpp file
    {
        A* construct_A( const char* name, int value ) { return new A(name, value ) ; }
        void destroy_A( A* pa ) { delete pa ; }
        A* copy_construct_A( const A* pa ) { return pa ? new A(*pa) : nullptr ; }
        A* assign_A( A* This, const A* that )
        { if( This && that ) *This = *that ; return This ;}

        const char* name_A( const A* This ) { return This ? This->name().c_str() : nullptr ; }
        void rename_A( A* This, const char* new_name ) { if(This) This->rename(new_name) ; }
        int value_A( const A* This ) { return This ? This->value() : 0 ; }
        void revalue_A( A* This, int new_value ) { if(This) This->revalue(new_value) ; }
    }
    //////////////////////////////////////////////////
#endif // __cplusplus

#endif // A_H_INCLUDED 


Sample C client:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
#include <stdio.h>
#include "a.h"

int main()
{
    A* pa = construct_A( "subba", 5 ) ;
    A* pa2 = copy_construct_A(pa) ;

    puts( name_A(pa) ) ;
    printf( "%d\n", value_A(pa2) ) ;

    rename_A( pa, "stroustrup" ) ;
    puts( name_A(pa) ) ;
    puts( name_A(pa2) ) ;

    assign_A( pa, pa2 ) ;
    // etc

    destroy_A(pa) ;
    destroy_A(pa2) ;
}
Topic archived. No new replies allowed.