RSS Feed
Download our iPhone app
Browse DevX
Sign up for e-mail newsletters from DevX

By submitting your information, you agree that devx.com may send you DevX offers via email, phone and text message, as well as email offers about other products and services that DevX believes may be of interest to you. DevX will process your information in accordance with the Quinstreet Privacy Policy.


A Guide to C++ and C Interoperability  : Page 2

Using C++ code in C apps is difficult and tricky, though not impossible, contrary to popular belief. Find out how to share class declarations between the two languages and how to leverage C apps with high-end C++ features behind your C compiler's back.




Building the Right Environment to Support AI, Machine Learning and Deep Learning

UDT Sharing
The simplest form of sharing a declaration of a user-defined type (UDT) between C and C++ is sticking to the lowest common denominator of C. The following C struct can be used as-is in a C++ program:

typedef struct String { char * pstr; int size; } String;

C doesn't recognize the keyword class so you must stick to struct. In addition, using the same token for the tag (the name before the {) and the typedef name (the name following the }) guarantees that the following code will compile successfully in both languages:

//works both in C and C++ char buff[100]; String mystr; //no 'struct' before String mystr.pstr=&buff[0]; mystr.size=sizeof(buff);

And yet, C++ users would expect to find member functions, conversion operators, and overloaded operators in String. The fact that these C++ features will not be usable in C is no excuse for depriving C++ users of these conveniences. Your goal is to have a single declaration of String that will be shared both by C and C++ users, without sacrificing essential C++ features. How do you accomplish this feat?

A C++ Overhaul
All data members in String must remain implicitly public. protected and private are out of the question as they might break binary compatibility between C and C++. Additionally, all C++ features must appear inside an #ifdef-endif block like this:

typedef struct String { >#ifdef __cplusplus //anything you put here will be visible only from C++ #endif char * pstr; int size; } String;

Here's the augmented String struct:

typedef struct String { #ifdef __cplusplus char * getpstr() {return pstr;} void init(int sz=0) {pstr=sz? new char[sz]:0; size=sz;} operator const char* () const {return pstr;} int getsize() const {return size;} char& operator[] (int id) {return pstr[id];} const char& operator[] (int id) const {return pstr[id];} #endif char * pstr; int size; } String;

C++ users can now use String as an ordinary C++ class with member functions, overloaded operators and conversion operators:

String s={0}; //zero initialize all data members s.init(10); s[5]='a'; cout<<s<<endl; //invoking const char* conversion operator cout<<s.getsize()<<endl; delete[] s.getpstr(); //'delete[] s;' will work too

C users on other hand will keep using String like this:

#include <stdio.h> String s1; s1.pstr=(char *) malloc(10); s1.size=10; printf("%s\n", s1.pstr); printf("%d\n", s1.size); free(s.pstr);

Unbelievable as it may seem, the two code listings above use the same String type.

Comment and Contribute






(Maximum characters: 1200). You have 1200 characters left.



Thanks for your registration, follow us on our social networks to keep up-to-date