Jump to content

Mixing C and C++


Sauraen
 Share

Recommended Posts

The application code for MIDIbox Quad Genesis absolutely needs C++: pieces of VGM files have to be edited, which means dynamic memory allocation (and freeing). Even the playback engine, where one VGM file can be played by multiple "play heads" at different positions corresponding to different channels, is inherently object-oriented. So I started making the core VGM player in MIOS32 in a new C++ application. Just testing the MBHP_Genesis driver with a C++ project (app.cpp) works fine, no compilation issues, and I was able to get the driver mostly working. But I then added some more complicated object-oriented source files, and after they compile, they fail to link:

/usr/local/etc/mios32_toolchain/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7e-m/libc_s.a(lib_a-abort.o): In function `abort':
abort.c:(.text.abort+0xa): undefined reference to `_exit'
/usr/local/etc/mios32_toolchain/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7e-m/libc_s.a(lib_a-sbrkr.o): In function `_sbrk_r':
sbrkr.c:(.text._sbrk_r+0xc): undefined reference to `_sbrk'
/usr/local/etc/mios32_toolchain/bin/../lib/gcc/arm-none-eabi/4.7.4/../../../../arm-none-eabi/lib/armv7e-m/libc_s.a(lib_a-signalr.o): In function `_kill_r':
signalr.c:(.text._kill_r+0xe): undefined reference to `_kill'

and so on. Do you have any idea what could be going on? The application includes a number of C++ source files, one C source file, and of course a number of drivers and MIOS32 components in C. Does this have to do with the 'extern "C"' thing? Not exactly sure where I need that, but all my code compiled, so the C and C++ source files seemed to have found each other's headers.

The only reason I needed a C source file in the first place was to manipulate the timers (higher resolution than those provided in MIOS32_Timer), and putting things like TIM5->CNT in a C++ source file didn't work. So I wrapped all the timer accesses in C functions and then had the original C++ source file call them. Again, this compiles, and this part doesn't seem to fail to link, just those OS things above.

Link to comment
Share on other sites

I committed this code so you can take a look if you want. I also created a test project in apps/troubleshooting that has the same overall structure as my project, but which doesn't have the linker issues. This leads me to believe that my code is at fault (of course it is!), but I still don't know what I could have messed up that would lead to this kind of linker issue.

Link to comment
Share on other sites

Those error messages are related to memory allocation (sbrk_r) and clean up on termination, so don't be entirely surprised if they show up again later, because it looks like a library mismatch.

You can write object oriented code with dynamic memory usage in C, you know. Just pass a structure in as the first parameter, and use malloc/free. C++ is mostly just a load of cruft and baggage to hide doing the same thing.

Given you've had worries about performance for this project, you should keep a close eye on the overheads C++ will be introducing into your code base. Profiling, metrics, and some good test code will save you a lot of headaches later on.

Edited by lis0r
Link to comment
Share on other sites

I may do that, as the core object-oriented part which really needed that had to be changed anyway. We'll see.

The one thing is that I don't think I can use malloc and free. I looked at the OS source and there's a pvPortMalloc function, but I'm not sure if I can use that. And in the documentation of those functions, it mentions not being able to free memory after allocating it. But new and delete work fine (if less quickly). I would think they would actually call the C functions malloc and free, but there's a lot about low-level embedded stuff I don't know. Maybe TK can weigh in on this? Has anyone else done a big MIDIbox project in C++?

Link to comment
Share on other sites

malloc/free overlays are part of the programming model: http://svnmios.midibox.org/filedetails.php?repname=svn.mios32&path=%2Ftrunk%2Fprogramming_models%2Ftraditional%2Ffreertos_heap.cpp

Big C++ based MIDIbox application: http://svnmios.midibox.org/listing.php?repname=svn.mios32&path=%2Ftrunk%2Fapps%2Fprocessing%2Fmidibox_cv_v2%2Fsrc%2F (major object orientied code located in src/components)

I don't use dynamic object allocation, but prefer static instead for deterministic behaviour.

Btw.: please move your cpp_issues program to a different location, e.g. /playground.
The apps/troubleshooting directory is intended to collect troubleshooting applications for the users, and not to discuss programming problems.

Best Regards, Thorsten.

Link to comment
Share on other sites

Thanks TK. In previous projects I used all static allocation, but this one involves users editing these VGM files on the synth, and this requires arrays to change size and other dynamic stuff.

I deleted the cpp_issues directory as per your request. I would have made it in playground in the first place, but I didn't know if I would be able to get the project to build, due to it not being in a valid position in the mios32 directory tree.

Link to comment
Share on other sites

The static approach would be to declare oversized arrays, and only use as much as you need. This has the advantage that you never have to worry about allocation overheads, heap fragmentation, or running out of memory.

An alternative approach is to couple this idea with a pool (e.g. static array and usage bitmap) of fixed memory blocks. As well as eliminating the danger of fragmentation, you can conceptually reset the pool on mode change, removing dangling pointers.

A lot of these concepts are similar between embedded work and video games, so if you google for "memory allocation in games", you'll find some useful articles.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

Loading...
 Share

×
×
  • Create New...