I have c++ library .so. My co-worker is working on c program which will call c++ library from his c program. I told him to create Wrapper.h and Wrapper.cpp and use pointer for passing around c++ objects in his c program. However, I found that he was trying to modify our c++ library source code by adding Wrapper.cpp and header into our library .so directly. For example:
class A{ SetValueA(int); }
class B{ SetValueB(int); }
In his Wrapper.cpp, he wrote sth like this:
A a;
B b;
extern "C" SetValueA(int) {a.SetValueA(int); }
extern "C" SetValueB(int) {b.SetValueB(int); }
Then he recompiled our c++ library and includes Wrapper.h in his c program.
What I told him is to do sth like this:
In my Wrapper.cpp
extern "C" {
A* newClassA() {
return new A();
}
void SetValueA(A* v, int i) {
v->SetA(i);
}
B* newClassB() {
return new B();
}
void SetValueB(B* v, int i) {
v->SetB(i);
}
void deleteClassA(A* v) {
delete v;
}
void deleteClassB(B* v) {
delete v;
} }
Then I just compiled my Wrapper.cpp and linked with our c++ library. In his c program, he just need to include Wrapper.h and compile his c code, and then compile Wrapper.o and main.o(from main.c) by using c++ compiler.
His solution looks working too, he complained that the way I told him is more works. But I dont want him to change our c++ library coz nobody else will use Wrapper class from c++ library. Can you tell me which one is the better and why?
Yes, I also dont like his way using global variable in his wrapper.
I don't see why there is a need to change any library file to use global variables: the necessary change should b confined to Wrapper.cpp which is clearly part of the wrapper.
That said, I don't believe in the use of any [mutable] global object. They tend to be a problem in many different ways. That is, I'd agree that the proper approach to create a wrapper is to effectively deal with the necessary life-time management. I do realize that getting life-time management properly sorted in C is harder than in C++. The fix to that is to use C++, not to create unnecessary dependencies (I'm aware that this argument typically doesn't fly with C programmers).
The wrapper that your co-worker wrote is of course indiscutable due to the use of global variables, which introduce many issues into your library.
However, I believe, a well written library should export a C interface by itself, even if it uses C++ internally. For the simple reason that a C interface can be imported into virtually every language, while a C++ interface requires user code to be C++. Also, forcing this kind of wrapper into user code is likely to lead to a proliferation of different wrapper.cpp versions, all of which are incomplete and out of date in different ways.
As such, I would include code along the lines of your wrapper.cpp into your library. And I would certainly move it close to the code that it wraps, instead of bundling it all in one big, fat wrapper.cpp. That way it is much easier to check whether all your public methods have been wrapped properly.
Related
I need to have compile time constant in C code:
#define CLASSFROMCXX_SIZE /* compile time constant /*
In C++ code I could just write:
#define CLASSFROMCXX_SIZE sizeof(ClassFromCXX)
But I can't use ClassFromCXX in C code. I could write a function that returns sizeof(ClassFromCXX), but I need compile time constant, not some runtime value.
Is it possible to achieve without code generation? What existing code generation tools could I use to achieve this?
It is more a theoretical question, but as an example: I use some library written in C++ in C code, so I write wrapper in C. I have to store classes from C++ somehow. Related question is: How to call a c++ class and its method from a c file
But it uses heap allocation/stack allocation.
You can achieve the goal with Makefile or other compiling tools: compile a piece of C++ code to get the size of the class and assign the size to a macro. After that, you can pass the macro to compile your real code.
Take Makefile as an example:
CODE_TO_GET_SIZE := "\#include \"class_from_cxx.h\"\n\#include <iostream>\nint main() {std::cout << sizeof(ClassFromCXX);}"
CLASSFROMCXX_SIZE := $(shell printf $(CODE_TO_GET_SIZE) | g++ -x c++ - && ./a.out)
What you want is simply not possible. C does not understand C++ class definitions nor C++ object layout. Thus, there is no way a C compiler could compute the size of a C++ class…
I think your best bet here would be to turn the problem around. While C does not understand C++ classes, C++ does understand C structs (to some degree) and can link with C. Instead of a C++ class, define a C struct as well as functions that operate on objects of that type. These functions can be implemented and used across both, C and C++:
#ifdef __cplusplus
extern "C" {
#endif
typedef struct
{
int a;
float p[3];
} SomeThing;
void SomeThing_construct(SomeThing* obj, int arg);
void SomeThing_destruct(SomeThing* obj);
void SomeThing_doYourThing(const SomeThing* obj, float x);
#ifdef __cplusplus
}
#endif
As pointed out by n314159, you could then add a wrapper class around this basic interface to use on the C++ side of things.
I would try to avoid going down the code generation path unless absolutely necessary. For code generation to compute the size of a C++ class means that it has to invoke a C++ compiler at some point. Preferably the exact compiler that will be used to compile the rest of the code with exactly the same flags that will be used to compile the rest of the code (C++ object layout does generally not just depend on the compiler but may even be affected by certain compiler flags). You will want to write a tool that generates a header file that contains the code you need. You will want to integrate the compilation and running of this tool into your buildsystem. Think of the generated header file as a dependency that is to be built like, e.g., a library would be. How you would go about doing this exactly depends on your build system. In a Makefile, you can just add a target to build the header file. If you use CMake to generate your buildsystem, you would add your tool using add_executable, then use add_custom_command() to define how the header file is to be built, and then add the generated header file to the sources of a target…
My Problem is that I want to call some template function in C.
Therefore, I have declared an extern "C" function as a wrapper function, which calls this template function.
I know, that I need to compile the wrapper function, with the c++ compiler and then I get an object file, which I can link against a normal c-program.
The problem is, that I have written a header only C++ library, which I want to use in C, but in C I can't make the library header only anymore, once I need to link the C-program against the wrapper function.
So does there exist any way of generating a header only c-library, which calls the c++ template function? This method should work in GCC and it is absolutely no problem, if it is nonstandard, requires several pragmas, cli-parameters or something else.
I think, a possible solution would be to call gcc in C-mode on a file, where on a particular line, a switch from C to C++ inside the header file is possible. This C++ switch does the actual template call and than a switch back to the C-compiler is performed. Does some method exist?
e.g. like this:
#include <iostream>
#define SWITCH_TO_CPP_COMPILER() /*TODO: is this possible?*/
#define SWITCH_BACK_TO_C_COMPILER() /*TODO: is this possible?*/
#ifdef __cplusplus
extern "C" {
#endif
inline bool wrapper();
#ifdef __cplusplus
}
#endif
SWITCH_TO_CPP_COMPILER();
template<bool tmp>
constexpr bool template_func() noexcept {
return tmp;
}
inline bool wrapper() {
return template_func<true>();
}
SWITCH_BACK_TO_C_COMPILER()
#include <stdio.h>
int main() {
printf("%d\n", wrapper());
}
I have already looked at several questions, but they do not answer it:
C Wrapper for C++: How to deal with C++ templates?
how to write c wrapper around c++ code to expose class methods
Create a C wrapper around a C++ library that can be linked by a C linker
C wrapper around C++ library without unnecessary header files
The whole point of the C wrapper is to have the C++ compiler generate an object module for the instantiated template and the wrapper, and letting the C compiler be blissfully unaware of anything but the wrapper, known/invoked thorough an extern function declaration.
This thing cannot be header-only: a header is brutally included in the file that uses it, and that file is going to be processed by a C compiler, which then would have to be able to parse/instantiate the C++ template besides the wrapper function, and this is obviously not possible. Parsing C++ is already complex as it is, requiring to switch to a different language in mid-air is completely bonkers.
If you want to use your library into a "C proper" program you have to have an extra TU compiled by a C++ compiler. Otherwise, since however you think about this you need some C++ compiler being able to compile your template, just compile everything in C++ and, if you prefer, just use the C subset for the rest of the files.
You already have a dependency from a C++ compiler and most probably from the C++ standard library, so this isn't going to change much besides compilation speed in the grand scheme of things.
This in mind what Matteo wrote in his answer:
Convinced that what OP wants is impossible, I tried to find a substantive argument.
I compared the "Phases of translation" for C and C++.
The first phases concerning pre-processing look quite similar but starting with phase 7 (compilation) it becomes quite different.
I hardly doubt that any compiler can switch from C to C++ and back in the mid of a translation unit (if it is standard conform).
I have a small doubt.
I am adding some extra functions in a C++ code and these functions are getting called by functions of a class.
Is it necessary to make these extra functions a part of class or can a C++ class function call a C function?
If yes, how should the makefile be modified ?
Thanks!
As long as you have included some declaration and the C function is linked in it some point in the compilation, you can call C functions in any C++ function. For instance:
mycfunc.h:
void test(int x);
myfunc.c:
void test(int x) {
printf("%d\n", x);
}
Now, simply include the header file where you want to use the function. In your Makefile, simply make sure you include "myfunc.c" (or .o if you're compiling objects) in the final compilation.
C++ is not a pure object oriented language.
So you can use imperative form as it is in C ( even if it's modular or not ).
Some C functions not encapsulated in Objects are accessible using c* includes (ctime for instance).
You do not need to put them in a class. Functions exist in C++ just as in C so you can just use them. Just try it and ask again if you have trouble.
As you state that you add functions to a C++ project, just treat (and think of) all your code as C++. Put your new stuff in files using the same filename extensions as those of the rest of the project.
Edit in response to comment from OP:
Yes, no need to think about the distinction between C and C++ in this case. Just write .cpp files. And in the makefile, just add those files just as the other files are listed there.
The distinction between C and C++ is important if you have existing C++ code and need to use if from C, or for example if you have existing C libraries and need to call that from C++. In your case there's very likely no reason not to stick to C++. Unlike Java, it's completely natural to have free standing functions. There even many in the C++ standard library.
Now, if in your case it is good design to have free standing functions instead of adding to classes (modifying or using inheritance) is hard to tell given the information you have posted. But, if what you need to do can be done in a natural way without accessing the private parts of existing classes the answer may very well be yes.
I'd like to use Pure Data as a prototyping tool for my own library. I found out that Pure Data patches are written in C, but my library is written in C++. So how can I use this code in pure data? Since I haven't used plain C, I'd like to know how I could write a C wrapper for C++ classes and how do instantiate my classes then? Or do I have to rewrite everything in C?
You will need to write wrapper functions for every function which needs to be called. For example:
// The C++ implementation
class SomeObj { void func(int); };
extern "C" {
SomeObj* newSomeObj() {return new SomeObj();}
void freeSomeObj(SomeObj* obj) {delete obj;}
void SomeObj_func(SomeObj* obj, int param) {obj->func(param)}
}
// The C interface
typedef struct SomeObjHandle SomeObj;
SomeObj* newSomeObj();
void freeSomeObj(SomeObj* obj);
void SomeObj_func(SomeObj* obj, int param);
Note this must be C++ code. The extern "C" specifies that the function uses the C naming conventions.
You can also write objects for Pure Data using C++ using the flext framework.
Let me put it another way:
1) You can call C functions, data and libraries from C++ source, and you call C++ source from C.
2) Whenever C calls into C++ source, however, that source must be written in a C subset of C++.
3) Part of this is using "extern C".
4) Another part is using "#ifdef __cplusplus"
5) The links I cited above give plenty of details
6) I looked at the Pure Data site. You might have to make some "tweaks" to your library. You might wish to create a new header. But fundamentally, I think you can probably accomplish your goal of getting your library to integrate with Pure Data.
IMHO...
You can absolutely call C from C++ - no problemo!
Worst case, you might have to explicitly declare those functions you call from Pure Data as "extern C". But it's almost certain that Pure Data has already done that for you (you'll probably see "extern C" in the Pure Data header files.
Here's more info:
http://msdn.microsoft.com/en-us/library/0603949d%28v=vs.80%29.aspx
'Hope that helps!
I have a C++ library that provides various classes for managing data. I have the source code for the library.
I want to extend the C++ API to support C function calls so that the library can be used with C code and C++ code at the same time.
I'm using GNU tool chain (gcc, glibc, etc), so language and architecture support are not an issue.
Are there any reasons why this is technically not possible?
Are there any gotcha's that I need to watch out for?
Are there resources, example code and/or documentation available regarding this?
Some other things that I have found out:
Use the following to wrap your C++ headers that need to be used by C code.
#ifdef __cplusplus
extern "C" {
#endif
//
// Code goes here ...
//
#ifdef __cplusplus
} // extern "C"
#endif
Keep "real" C++ interfaces in separate header files that are not included by C. Think PIMPL principle here. Using #ifndef __cplusplus #error stuff helps here to detect any craziness.
Careful of C++ identifiers as names in C code
Enums varying in size between C and C++ compilers. Probably not an issue if you're using GNU tool chain, but still, be careful.
For structs follow the following form so that C does not get confused.
typedef struct X { ... } X
Then use pointers for passing around C++ objects, they just have to be declared in C as struct X where X is the C++ object.
All of this is courtesy of a friend who's a wizard at C++.
Yes, this is certainly possible. You will need to write an interface layer in C++ that declares functions with extern "C":
extern "C" int foo(char *bar)
{
return realFoo(std::string(bar));
}
Then, you will call foo() from your C module, which will pass the call on to the realFoo() function which is implemented in C++.
If you need to expose a full C++ class with data members and methods, then you may need to do more work than this simple function example.
C++ FAQ Lite: "How to mix C and C++ code".
Some gotchas are described in answers to these questions:
[32.8] How can I pass an object of a C++ class to/from a C function?
[32.9] Can my C function directly access data in an object of a C++ class?
Main gotcha: exceptions can not be caught in C. If there is the possibility of an exception rising in the C++ code, either write your C code or your C++ wrappers very carefully. Conversely, exception like mechanisms (i.e., longjump) in the C code (as found in various scripting languages) are not required to invoke destructors for C++ objects on the stack.
you can mix C/C++ code. If your main() function in in C++, then you just need to make sure your c functions are declared
extern "C"
If your main is C, then you are probably OK except for static variables. Any constructors with your static variables are supposed to be called before main() start. This won't happen if C is your main. I you have a lot of static variables, the best thing to do is to replace static variables with singletons.