tags:

views:

386

answers:

8

I have to import/translate the code from one C++ class so that I may use it in a C program.

The C program is large and has lots of dependencies on C libraries both open and closed.

The C++ Class .cpp file is 650 lines

I have no experience mixing C and C++ so even though I have looked at one guide on how to do it, I am not convinced which way to go.

I only have to use the C++ code in a few spots (fairly isolated useage

I am using gcc (gcc/g++)

It is a linux environment

So what do I have to do to import it? and will it be less time than translating?

Thanks,

Mike

+6  A: 

You need to create functions in C++ that are 'extern "C"', so they are callable from C.

You can get OO by making the this pointer explicit (and of type void *), with the implementation casting the pointer and forwarding to the real member function.

Richard
+6  A: 

This might be useful: http://www.parashift.com/c++-faq-lite/mixing-c-and-cpp.html

ChrisW
+4  A: 

In your C++ code, you must use the extern "C" construct to instruct the compiler/linker to generate compatible linkage so that the C code can call your C++ code.

extern "C"
{
   void my_function_that_can_be_called_from_c()
   {
      // ...
   }
}

C code doesn't know anything about objects, so you can't easily use C++ objects from C. A common technique is to manipulate C++ objects inside the "externed" function.

Brian Neal
+11  A: 

Hmm, 650 lines is not too long - I'd re-write it. You will probably spend at least as much time trying to wrap it, and you may find maintaining the result difficult.

anon
+1  A: 

If you want to turn the C++ class into a Linux shared library accessible to your C programs, this answer to a previous question shows you how with a small example class.

Bill the Lizard
+3  A: 

Say you have the following C++ class:

#if __cplusplus // only C++ programs see this part of foo.h

class foo {
public:
    // a couple constructors
    foo();

    foo( int);

    // and a couple methods
    bool dosomething();
    bool doSomethingElse( std::string const&);

private:
    // a bunch of private stuff which is immaterial to the C interface
}

#endif

What you can do is have a set of C-callable functions that wrap the C++ interface:

// both C and C++ programs can see this part of foo.h

#if __cplusplus // but C++ programs need to know that no name mangling should occur
extern "C" {
#endif

struct CFoo_struct;
typedef struct CFoo_struct foo_t;   // used as a handle to a foo class pointer

// constructors

foo_t* CreateFoo( void);
foo_t* CreateFoo_int( int);

int CFooDoSomething( foo_t*);
int CFooDoSomethingElse( foo_t*, char const*);

#if __cplusplus
}               // end the extern "C" block
#endif

Then the implementation in foo.cpp might look something like:

// in foo.cpp
extern "C" {

    struct CFoo_struct {
    };


    // constructors

    foo_t* CreateFoo( void) 
    {
        foo* pFoo = new Foo;

        // a bit of ugliness - the need for this cast could be 
        //  avoided with some overhead by having the foo_t
        //  struct contain a foo* pointer, and putting a foo_t
        //  structure inside the foo class initialized with 
        //  the this pointer.

        return reinterpret_cast<foo_t*>( pFoo);
    }

    // something similar for CreateFoo_int()...



    // method wrappers

    int CFooDoSomethingElse( foo_t* pHandle, char const* s)
    {
        foo* pFoo = reinterpret_cast<foo*>( pHandle);

        std::string str( s);

        return pFoo->doSomethingElse( str);
    }

    // something similar for CFooDoSomething()

} // end extern "C" block
Michael Burr
A: 

There's various things you can do.

You can rewrite it in C. Without actually seeing the code, I don't know how much trouble that would be. Much C++ code is simply C with a few addons, and some makes heavy use of templates and overloaded functions and such.

If you're not doing this, you need to make it communicate well with C. This means providing an interface for C, and surrounding it with extern "C"{ ... } so the C++ compiler will know to make the interface C-compatible. Again, without knowing something of the C++ code, I can't tell how much work this would be. You'll need the wrapper for either of the following solutions.

You can make this a C++ project, surround every C file with extern"C" { ... }, and just link it in. If you have any C++ files, the whole compilation has to be C++.

You can make a separate library to be linked in.

What you can't do is compile C and C++ together with a C main() function, or with a C compiler. C++ is more demanding, and requires more from the main() function.

You could always try recompiling the C files you're using as C++, and wrapping the .h files for the libraries in extern "C" { ... }. Well-written C90 isn't that far from being legal C++ (although the C99 standard moved away from that some), and the compiler will flag any conversion problems you find.

Which of these is the best idea for you depends on questions like: How easy is the C++ code to convert? How easy is it to write a C wrapper for the C++ functionality you want? How many changes are you willing to make to the C code? How familiar are you with making a Linux library?

David Thornley
A: 

can i complete a program in C++ and then convert it in to a c++ program with classes?? ps: i from belgium

jon