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!
Related
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).
So basically I am trying to integrate a custom C library into an existing C++ project. I have various C++ objects that will need to be stored/loaded into a C DB and interface with various C functions. I need to convert my C++ objects into C structs, and back again. I have made progress, but am running into memory allocation issues.
I know I haven't included any code here, but I am just wondering if there are any general tips for this task? I have seen the void* used in extern "C" for generic C++ objects, but I really need to load/save data from/to C++ objects and C structs.
If I haven't worded this correctly, please ask!
Use extern "C" to declare your C structures:
extern "C" {
struct some_c_struct {
int field1;
char *p;
};
};
Then, in your C++ code you can use some_c_struct just like any other C++ class or struct, with guaranteed C compatibility, and successfully pass them to and from the C code library that you're using.
Practically speaking, the extern "C" declaration isn't needed, but all the language lawyers demand it. Additionally, your struct cannot use any C++-specific features, like virtual functions.
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.
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 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.