使用 C++ C语言的API?
有一天,我决定开始用普通的旧 C 语言编写一款视频游戏。
这很有趣,三个月后(我有时几乎没有时间离开工作)我发现自己需要一些物理引擎。
我决定使用 Bullet 物理引擎,因为它似乎是满足我需要的更好的引擎之一。
然后,我发现 Bullet 并没有真正的 C API,而只有完整的 C++ API。其 C API 未维护。
经过一天的咒骂,我将我的项目“转换”为 C++,这是一个大胆的声明,表示我对所有堆分配进行了类型转换,我使用 new 和 delete 而不是 malloc 和 free,并将一些定义包装在 'extern "C" 中{ ... }'。
有些人可能会因为我这样做而开枪打死我,但我没有看到其他选择来使用性能任务的东西,比如这个物理引擎,它只有一个 C++ API,用 C 语言。
所以现在,我用 g++ 进行编译,而仍然主要编写“C”代码。 我发现自己有点不高兴,因为代码感觉不再那么纯粹。
C++ 给了我一些奇怪的错误消息,虽然我并不反对这种语言,但我经常不喜欢 g++ 解析器。 除了我现在可以愉快地将物体弹到彼此之外,我所钟爱的项目的一些小而纯粹的东西现在已经被遗弃了。
我想知道我是否做了正确的事。我可以寻求一些建议吗?我是否应该继续使用 C++ 编译器来处理我的“主要”C 代码?是否有其他方法可以在 C 语言中使用此 API,而不会影响性能或过度维护工作?
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 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?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
好吧,您的项目需要一个组件,您无需从头开始重新发明它,而是重用了现有的软件。这对我来说确实听起来不错。
你完全不用担心。 C++ 几乎 100% C 兼容。这样做不会受到任何处罚。由于更严格的类型系统,您实际上已经获得了更好的编译时检查。
不,如果不将代码转换为 C++,则无法使用 C 语言的 API。 C++ 标识符被破坏:这意味着,即使您准备好使用普通 C 中的 C++ API,您也不知道如何引用它们。理论上这是可能的,但实际上不可能。
你的方法是正确的。
祝那场比赛好运!
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.
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.
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!
我认为你过于关心那些并不是真正问题的事情。你说有些纯洁已经消失了。嗯,我能理解这一点。您用 C 编写了它,然后意识到必须使用 C++ 来使用所选的 API,因此将其硬塞进去。现在它不再像您的宠物宝贝了。这是一个潜意识问题,而不是编程问题。
我建议你硬着头皮(哈哈),用 C++ 重写你的项目。然后又会变得纯洁,一路上你会学到很多东西,不会觉得你的C号孩子被鸡奸了。
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.
根据引擎不同子系统的紧密耦合程度,用不同语言编写引擎的不同部分可能是可行的。
例如,您可以将物理部分分解为 C++ 模块,该模块导出 C API,并让应用程序的其余部分保留在 C 中。但是,用 C++ 编写系统的核心部分并重构您的应用程序可能更有意义。将现有的 C 代码分成单独的模块。
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.
如果你想用 C 语言编写你的项目,就用 C 语言编写它并为库制作一个 C 包装器;查看这个问题以获得一些相关建议。
否则,用 C++ 重写您的项目;但是,请不要到处编写另一个带有一些 C++ 的 C 项目,根据我的经验,这些项目很快就会变得一团糟(如果你用 C 思维方式编写代码,但调用 C++ 代码,当异常出现时,奇怪的事情就会开始发生)添加到混合物中)。
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).
不必担心主要编写 C 代码并使用 C++ 进行编译。只要采用 new/delete 而不是 malloc/free 就可以了。使用 new 的优点是不必将结果强制转换为正确的指针类型(C++ 中不允许从 void* 隐式强制转换为其他指针)并且 new 永远不会返回无效指针。不过你失去了 realloc() 。 (不,甚至不要考虑将 new/delete 与 realloc 混合:))
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 :))
将项目保留为“纯 C”的唯一原因是因为源代码兼容性、工具支持或因为语言标准(MISRA-C 等)。 “我希望它感觉纯净”可能不是一个非常理性的论点。
如果出于此类原因将代码保持为纯 C 很重要,那么您可以用 C++ 编写一个“包装器”DLL(假设是 Windows),它负责与您的第 3 方 API 进行所有通信。当然,你会得到相当多的开销。
这些奇怪的错误消息无疑是由 C++ 中更严格的类型引起的,根据具体情况,这可能是福是祸。当遇到危险的隐式类型转换(整数提升等)时,C++ 编译器更有可能会采取行动,并且它可能会强制执行更严格的“常量正确性”。但与此同时,它会抱怨 void 指针,这在 C 中被认为是良好的泛型编程,但在 C++ 中是危险的、草率的并且可能是多余的。
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++.
一种选择是使用 LLVM 将 C++ 代码转换为 C。请参阅该项目网站上的常见问题解答:我可以将 C++ 代码转换为 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?