So it's been a while since I've used straight C. And I'm on a project where I'm working on an API in C++. Most of these methods are just C anyway, and all of the return values are C structures. Except one. One method I need to return a vector<string>. Now here's my question. Is C++ methods/libraries/whatever callable from C? I ask because I don't know if the people using the API are going to be writing in C or C++, and I feel like I should be returning only C structures. That would require me to return a char**, right?
I hope that made sense, if not:
tl;dr version - Can I call a C++ method from C if it returns a C structure, and if so is the best (only?) equivalent return value of vector<string> -> char**?
Update: The C++ methods are simply global methods. There's no classes or object oriented stuff in them. The ONLY thing that's specific to C++ other than my vector question is a few stringstreams
No, C cannot use C++ features that are not also available in C. However, C code can make use of C++ code indirectly. For example, you can implement a C function using C++, and you can use opaque types in the interface so that the signature uses void*, but the implementation uses a C++ class.
The equivalent of vector<string> in C is probably closer to:
typedef const char* c_string_type;
typedef struct c_string_array {
c_string_type* c_strings;
int c_strings_count;
} c_string_array_t;
With opaque types, you would have something along the lines of:
typedef void* c_string_array_t;
int c_string_array_length(c_string_array_t array);
const char* c_string_array_get(c_string_array_t array, int index);
You could then secretly (in the C++ implementation) cast std::vector* to void*.
You can technically call anything from C, as long as a C-visible function name is given (prototypes etc. are ignored at the ABI level). Of course you can't expect correct results if C isn't able to generate the parameters in the expected fashion. Generally the obvious solution is to simplify the interface down to the C level. char ** is an excellent choice for greatest common denominator with a vector<string>. Not only that, if you know what you intend to do with it, quite possibly faster (and cleaner IMHO).
With respect to the C visibility: The function name cannot be shared with any other C visible functions. If you wish your C++ function to be callable from C, this might be a good example of the prototype:
extern "C" char **lots_of_strings();
If the parameter signature differs, C++ will let you overload with functions visible only from C++, and allow them to coexist with the C version:
vector<string> lots_of_strings(int);
extern "C" char **lots_of_strings();
If you wanted to provide several ways to call it, appropriate for the calling language, you might try this (ignoring the evils of late initialization, and the fact that bool exists in C):
bool lots_of_strings(vector<string> &);
extern "C" int lots_of_strings(char ***);
Whatever lots_of_strings(SomeArrayType &);
Keeping in mind that in every case, C++ will choose the definition with the best matching signature to the call site, and C will take whatever it can (which is always a single function with a matching name).
You'll find it useful to hide C++isms from C by combining #ifdef with the macro __cplusplus.
See this FAQ. Basically, you can't call C++ methods (member functions), but you can call free-standing functions if they're declared with extern C. char ** is not the only possibility, but it's probably the most straight-forward. You can return a dynamically allocated array of char *. You will have to use an out parameter to provide the length to the caller (you could NULL-terminate it, but that's probably not ideal). E.g.
char **get_string_list(size_t *len)
{
char **array;
size_t actual_len;
// ...
*len = actual_len;
array = (char **) malloc(sizeof(char *) * actual_len);
// ...
return array;
}
You must somehow free the memory. Either provide a function or document how the caller should do it. Don't forget to free the individual strings if they're dynamically allocated.
I read some lines about this some time ago, and iirc you can use c++ code/structures that would compile in C. But there is some thing about static initialisation, if i understood correct, you should write your main function in c++ to guarantee that this s.i. is done, C main does not do.
If you intend to offer the same functionality to both C and C++ I would try to offer two entry points so that you can adapt one to the other. Note that while you can settle for an interface that can be used both from C and C++, in most cases the C interface will not be ideal for C++ usage (using char** might be a good solution for C, but having users convert that back to C++ types and performing cleanup can clutter user code) and vice versa.
If you have the possibility to modify the code that you're calling I would suggest changing the function from returning an vector to something like:
unsigned int MyFunction(char* buff, unsigned int numLines, unsigned int stride)
Where numLines is the amount of allocated strings and stride is the size of the strings. That way your function doesn't need to allocate any memory that you need to worry about later. It's all handled by the caller. The return value of the function is the amount of strings that was used.
Related
I'm working on a legacy code base that has this pattern:
struct sometype_t { /* ... */ };
int some_method(void *arg1) { // void pointer
((sometype_t*)arg1)->prop1; // cast
}
Is there any (common) scenario where it would be unsafe to use sometype_t * instead of void *?
int some_method(sometype_t *arg1) {
arg1->prop1;
}
The pointer isn't passed across ABIs or into 3rd-party libraries; it stays entirely within C++ code that we own.
It's usually not a good choice, but the only situation I'm aware of where this really make sense is if you want to have stateful callbacks passed into a function, without using templates:
void takes_callback(void(*f)(void*), void * data);
Basically the gist is that since you aren't using templates, you have to fix the function signature you accept (of course, it can and often does take other arguments and return something as well). If you just call the function with your own parameters though, the function can only hold state between calls via global variables. So instead the contract for takes_callback promises to call f with data as a parameter.
So, if you wanted to use some_method as a callback in such an API, you would have to have it take void*, and do the cast internally. Obviously, you are throwing away type safety here, and if you happen to call takes_callback with &somemethod and a pointer to anything that's not a sometype_t you have UB.
Having a C ABI is one reason to avoid templates, but it's not the only one. Maybe they were worried about code bloat, or wanted to keep the implementation in a .so so that versions could be upgraded without recompiling, etc.
The obvious common scenario that immediately comes to mind is callbacks for some functions from C standard library.
For example, the proper way to write the comparison callback for std::qsort is to declare the function with two const void * arguments and then cast them to proper specific pointer types inside the callback.
Replacing these const void * parameters with specifically-typed pointers will simply prevent the code from compiling.
I am trying to implement the use of a C++ library within my project that has not used const modifiers on its access functions. Up until now I have been using const in all of my code but this new library is causing two main problems:
Functions where the arguments are passed as const references cannot use the argument's access functions if these arguments are of a type defined by the library.
Classes with member objects of types defined by the library cannot use the access functions of these objects within a const function.
What is the best way to overcome this issue? The easiest solution would be to simply remove all use of const from my code but that would be quite frustrating to do.
Additional info: In this case I do have access to the source code and can see that the access functions do not modify anything. I omitted this information as I was interested in the more general case as well. For my scenario, const_cast appears to be the way to go
PS The library writer is not evil! It is more a bit of rough and ready code that he has kindly open sourced. I could ditch the library and use something more professional as others have noted. However, for this small time-constrained project, the simplicity of the interface to this library has made it the best choice.
How easy is it to tell whether the functions in the library actually modify anything or not?
If it's easy to tell, and they don't, then you can const_cast your const pointer/reference to non-const and call the library function. You might want to throw a wrapper around the library classes to do this for you, which is tedious and verbose but gets that code out of your classes. This wrapper could perhaps be a subclass that adds some const accessors, depending whether the way you use the library class allows that to work.
If it's hard to tell, or they do modify things, then you need to use non-const instances and references to the library classes in your code. mutable can help with those of type (2), but for those of type (1) you just need to pass non-const arguments around.
For an example of why it might be hard, consider that the library author might have written something like this:
struct Foo {
size_t times_accessed;
int value;
int get() {
++times_accessed;
return value;
}
};
Now, if you const_cast a const instance of Foo and call get(), you have undefined behavior[*]. So you have to be sure that get really doesn't modify the object it's called on. You could mitigate this a bit, by making sure that you never create any const instances of Foo, even though you do take const references to non-const instances. That way, when you const_cast and call get you at least don't cause UB. It might make your code confusing, that fields keep changing on objects that your functions claim not to modify.
[*] Why is it undefined behavior? It has to be, in order that the language can guarantee that the value of a const object never changes in a valid program. This guarantee allows the compiler to do useful things. For example it can put static const objects in read-only data sections, and it can optimize code using known values. It also means that a const integer object with a visible initializer is a compile-time constant, which the standard makes use of to let you use it as the size of an array, or a template argument. If it wasn't UB to modify a const object, then const objects wouldn't be constant, and these things wouldn't be possible:
#include <iostream>
struct Foo {
int a;
Foo(int a) : a(a) {}
};
void nobody_knows_what_this_does1(const int *p); // defined in another TU
void nobody_knows_what_this_does2(const int *p); // defined in another TU
int main() {
const Foo f(1);
Foo g(1);
nobody_knows_what_this_does1(&f.a);
nobody_knows_what_this_does2(&g.a);
int x;
if (std::cin >> x) {
std::cout << (x / f.a); // Optimization opportunity!
std::cout << (x / g.a); // Cannot optimize!
}
}
Because f is a const object, and hence f.a is a const object, the optimizer knows that f.a has value 1 when it's used at the end of the function. It could, if it chose, optimize away the division. It doesn't know the same thing about g.a: g is not a const object, a pointer to it has been passed into unknown code, so its value might have changed. So if you're the author of nobody_knows_what_this_does1 or nobody_knows_what_this_does2, and you're thinking of const_casting p and using it to modify its referand, then you can only do it if you somehow know that the referand is non-const. Which normally you don't, so normally you don't use const_cast.
I think you have the following options:
If you are sure the library is working as it should if it was using the const specifier, you could use const_cast<> to remove the const-ness of your objects when dealing with the library
Alternatively, you could make non-const copies of your const objects and pass those to the library, then update the changes to the non-const parts on your original objects
Search for another library that is const-correct
remove all const from your code (not recommended)
Another option is to copy your object into a modifiable temp and pitch it. This is probably the safest thing to do if you're in the circumstance where your class offers a copy constructor and it's not too expensive. This has been my preferred method when it's available, as I know it's 100% safe. Silly example:
int getInfoFromString(String& str); //what?? why isn't str const :(
So I do
String temp(str);
int stuffINeed = getInfoFromString(temp);
//happy
If the library's interface is not big, you can create a wrapper, where you would adjust your code to expected types, by either casting or making a copy of parameters, which are passed to library's functions.
But do not degrade your code in order to use the library.
Another suggestion: Are you familiar with the mutable keyword? If you use it correctly, it might actually accomplish exactly what you're trying to do, with exactly one word added to your code. This keyword can evoke religious opinion at the level of goto because it's probably used as a kludge for every hundred times that it's used because it really is the best design option. In your case, it's debatable which it is but I think it fits the spirit: your annoying library object is something that can be fake-modified without breaking the semantic const-ness of your methods, so go ahead.
class Outer {
mutable Inner inner;
public void foo() const {
inner.nonConstMethod(); //compiles because inner is mutable
}
};
gcc 4.4.4 c89
I was just reading a discussion at DevX about calling C++ code from C since I have to do something similar. I am just wondering what user Vijayan meant by "make sure that non POD types in C++ are opaque to C clients."
Many thanks for any suggestions,
C can only deal with POD types.
Consequently, you cannot pass objects of non-POD types to C programs (by value). Also, if you pass pointers of non-POD types to C programs, they can't interact with the objects pointed to.
POD = Plain old data structure = C structs, no virtual methods, etc. You need to write wrapper functions for C to access non-POD types (i.e., classes).
More on POD:
http://en.wikipedia.org/wiki/Plain_old_data_structure
For a type to be opaque means you can't look inside it: it's a "black box" that can be passed around but not inspected or manipulated directly by the C code. You typically refer to the object using either heap-allocated memory and void*s, or using functions to determine the necessary length and buffers.
For example, a C++ object might contain a std::string, but the layout of a std::string is not specified in the C++ Standard, so you can't write C code that directly reads from or writes to the string (at least, not without having a total understanding of the std::string layout, manually revalidated every time the compiler/STL is updated).
So, to allow C code to access the object, you might write C-callable functions such as:
#if __cplusplus
extern "C" {
#endif
void* object_new();
const char* object_get_string(void* p_object);
void object_set_string(void* p_object, const char* s);
void object_delete();
#if _cplusplus
}
#endif
With C++ implementation ala:
class Object { std::string string_; ... }
void* object_new() { return new Object; }
const char* object_get_string(void* p) { return ((Object*)p)->string_.c_str()); }
...
Here, the object_XXX functions provide the C code with a safe way to use the Object.
Making the type opaque means, as per the line in the link:
typedef struct base base ; /* opaque */
makes the name of the handle available to C code, but not the definition of the type. This means that the C code cannot access any members directly, but has to go through the interface functions.
Note that you do not have to make a cast to a generic , i.e. void*, pointer, although doing so is one option, as per 9dan's answer.
Note that such a style of interface is in my experience a very nice way to manage encapsulation even in pure C code, just as in the standard C streams library.
Making opaque to clients means nothing special. C stream file I/O (FILE* f = fopen) API is the typical example that present opaque handle to clients.
Apparently C can not handle non-POD type so you must hide C++ implementation from C clients but provide access method.
Example:
C++ Implementation
class MyLibrary {
MyLibrary();
~MyLibrary();
int DoSomething();
...
}
Declaration for C clients
typedef void* OPAQUEHANDLE;
extern OPAQUEHANDLE MyLibrary_OpenLibrary();
extern void MyLibrary_CloseLibrary(OPAQUEHANDLE h);
extern int MyLibrary_DoSometing(OPAQUEHANDLE h);
Implementation for C clients (in .cpp file)
extern OPAQUEHANDLE MyLibrary_OpenLibrary()
{
return new MyLibrary;
}
extern void MyLibrary_CloseLibrary(OPAQUEHANDLE h)
{
delete (MyLibrary*) h;
}
extern int MyLibrary_DoSometing(OPAQUEHANDLE h)
{
return ((MyLibrary*)h)->DoSomething();
}
In C++ the only way to pass an array to a function is by pointer, considering following
functions:
void someFunc(sample input[7]){
//whatever
}
void someFunc(sample input[]){
//whatever
}
void someFunc(sample (& input)[7]){
//whatever
}
All above function parameters are identical with following function parameter when the function is not inlined:
void someFunc(sample * input){
//whatever
}
Now to pass the array with value we have to put it in a structure like below:
struct SampleArray{
public:
sample sampleArray[7];
};
Now I'd like to know if anyone knows the reason behind this design in C++ standard that makes passing pure arrays by value impossible by any syntax and forces to use structs.
Backward compatibility reasons. C++ had no choice but to inherit this behavior from C.
This answer to the earlier similar question addresses the reasons why such behavior was introduced in C (or, more specifically, why arrays and arrays within structs are handled differently by the language).
C++ adopted that part of C, but added the ability to pass arrays by reference (note that your third version of someFunc passes the array by reference, and is not equivalent to using a pointer to its first element). In addition, C++ includes various container types that can be passed by value (recently including std::array)
Probably as a function of its C ancestry. Arrays being just pointers to memory it'd be kind of hard for that to be done transparently without generating extra code by the compiler. Also it's trivial to implement a container class that does lazy copy on write, which will perform better.
I need to write my 4-5 .cpp and .h file to c code. In C++ code we have defined a class, constructor, destructor, function.
How to convert them in C code?
Can somebody give me example of it so that i can implement it or provide link so that I can better explore it to my C code?
How to implement all the functionality i mean constructor,destructor,functions of class in C ?
convert all classes to data structures (typedefs)
replace constructors and destructors with functions that use malloc/calloc and free and return/take pointers to your typedef'd structures
eliminate polymorphism; if this is not possible then implement a message-dispatching function for each typedef (a big switch statement) and represent messages as constant integers
alter all functions to take a pointer to the appropriate typedef
Note that typedefs do not support subtyping, so all inheritance will have to be converted to composition.
There are a lot of considerations and things that need to change, but I think what you want to do is emulate object oriented code in C.
Basically for each of your classes you need to take out the functions and leave only the data members inside the class/struct (you will rename class to struct and remove public/private/protected specifiers).
Then you need to add a first parameter to each of those functions which is a pointer to the struct to operate on.
Nearly all typical OO C++ code is just snazzy syntax around the old technique of creating libraries that created a "cookie" and required it to be passed into every call. So if none of the classes have virtual methods (no runtime dispatch) you should be able to do the following:
Think of all class names as "facility" or "library" names.
Put all data members of the class into a struct named classname (what the class used to be named)
Turn all the methods into functions named classname_methodname.
Add a pointer to the classname struct to the parameter list of all the functions (methods) for that class.
Turn the constructors into a functions named classname_construct(# for overloads perhaps) and the destructor into a function named classname_destruct.
Change all the method calls in other code from objectname.methodname (...) to classname_methodname (objecname, ...).
This is the tricky part: You will have to put in code to call the destructors manually, since those are automagically called in C++.
Taking the example given in the comments:
class QtCommandData {
public:
QtCommandData(unsigned short net, unsigned short command,
unsigned long n_data_bytes, unsigned short flgs,
unsigned char* data = NULL);
QtCommandData();
~QtCommandData();
public:
unsigned char* m_pData;
int m_Async;
protected:
unsigned int m_nDataBytes;
unsigned int m_BytesAllocated;
protected:
int Fill_Trailer();
};
...becomes (I'll abbreviate the "facility name" from QtCommandData to QtCD):
typedef struct {
unsigned char* m_pData;
int m_Async;
unsigned int m_nDataBytes;
unsigned int m_BytesAllocated;
} QtCD;
QtCD_Construct(QtCD * handle,
unsigned short net, unsigned short command,
unsigned long n_data_bytes, unsigned short flgs,
unsigned char* data);
QtCD_Destruct(QtCD * handle);
QtCD_Fill_Trailer (QtCD * handle);
That's the general idea. Templates and dynamic dispatch and a few other things may throw you a monkeywrench or two, but I'm sure you are up to the challenge. :-)
For functions you also need to prevent the C++ compiler from name mangling if you want to link a C++ library to a C program, so you add blocks in your headers like
#ifdef __cplusplus
extern "C" {
#endif
/* Some functions here */
#ifdef __cplusplus
}
#endif
C does not directly support the OOP paradigm. Translating an OO design or code to C is a fairly simple mechanical process but not one that could not reasonably be fully covered here perhaps. There is at least one thread on the subject already: Can you write object-oriented code in C? with links to resources.
If your code uses the more complex C++ features such as generic programming, polymorphism and multiple inheritance, your work may be more difficult than it is worth. However C and C++ can interoperate fairly easy. Why would you not just provide a C wrapper around your C classes?