Using C++ API in C?
One day I decided to start writing a video game in plain old C.
It was a lot of fun, and three months later (I sometimes have little time away from the job) I found myself in the need of some physics engine. I decided to use Bullet physics engine, because it seems like one of the better ones out there for what I need. Then, I found out Bullet doesn't really have a C API but only a full C++ API. Its C API is not maintained. After a day of cursing, I 'converted' my project into C++, which is a bold statement for saying I typecasted all heap allocation and I use new and delete instead of malloc and free, and wrapped up some definitions in 'extern "C" { ... }'. Some people would probably shoot me for doing that, but I saw no other option to using a performance-tasking thing such as this physics engine, which开发者_如何学C only has a C++ API, in C.So now, I'm compiling with g++, while still writing mostly "C" code. I find myself a little less happy, because the code no longer feels as pure.
C++ gives me some strange error messages, while I have nothing against the language I often do not like the g++ parser. Aside from the fact that I can now happily bounce objects into each other, some of the smallness and purity of my pet project has been deserted now.I'm wondering if I did the right thing. Can I ask for some advice, should I just carry on and not worry about using a C++ compiler for my 'mostly' C code? Are there other ways to use this API in C without any performance hits or overdone maintenance work?
I'm wondering if I did the right thing.
Well, you needed a component for your project, and instead of inventing it again from scratch, you reused an existing piece of software. It actually sounds right to me.
Can I ask for some advice, should I just carry on and not worry about using a C++ compiler for my 'mostly' C code?
You don't need to worry at all. C++ is almost 100% C compatible. There are no penalties on doing that. You have actually earned better compile-time checkings due to a much stricter type system.
Are there other ways to use this API in C without any performance hits or overdone maintenance work?
No, you can't use the API in C without converting your code to C++. C++ identifiers are mangled: this means that, even if you were ready to use the C++ API from plain C, you wouldn't know how to refer to them. Theoretically this is possible, in practice it isn't.
Your way is the correct one. Good luck with that game!
I think you're overly concerning yourself with things that aren't really problems. You say that some of the purity has gone. Well, I can understand this. You wrote it in C and then, realizing you had to use C++ to use an API of choice, shoehorned it in. Now it doesn't feel like your pet baby anymore. This is a subconscious issue, not a programming one.
I suggest you bite the bullet (haha), and rewrite your project in C++. Then it will be pure again, you'll learn a lot on the way, and won't feel like your C-child is being sodomized.
Depending on how tightly coupled the different subsystems of your engine are, it might be feasible to write different parts of the engine in different languages.
For example, you could factor out the physics part into a C++ module which exports a C API and let the rest of your application stay in C. However, it might make more sense to write the central part of the system in C++ and refactor your existing C code into seperate modules.
If you want to write your project in C, write it in C and make a C wrapper for the library; have a look at this question for some advice about it.
Otherwise, rewrite your project in C++; but please, don't write yet another C project with some C++ here and there, in my experience these projects can quickly become a mess (and if you write code with a C mindset but calling C++ code weird things start to happen when exceptions are added to the mix).
Don't worry about writing mostly C code and compiling it with C++. Just adopt using new/delete instead of malloc/free and you'll be fine. The advantage of using new is that you don't have to cast the result to the proper pointer type (implicit casts from void* to other pointers are disallowed in C++) and that new will never return an invalid pointer. You loose realloc() though. (And no, don't even think of mixing new/delete with realloc :))
The only reasons you would keep a project as "pure C" are either because of source code compatibility, tool support, or because of language standards (MISRA-C etc). "I want it to feel pure" is probably not a very rational argument.
If keeping the code as pure C for such reasons is important, your could have written a "wrapper" DLL (assuming Windows) in C++, which does all the communication with your 3rd party API. You'd get a fair bit of overhead of course.
The strange error messages are no doubt caused by the stricter typing in C++, which can be a bless or a curse depending on the situation. A C++ compiler will be more likely to slap your fingers when encountering dangerous implicit typecasts (integer promotions etc) and it will likely enforce stricter "const correctness". But at the same time, it will moan about void pointers, which are considered good generic programming in C, but dangerous, sloppy and possibly redundant in C++.
One option is to convert the C++ code to C using LLVM. See this FAQ from the project's website: Can I convert C++ code to C code?
精彩评论