C2mx2 lives!


I finally got around to taking a good look at using ‘libclang’ to help with converting native ‘c’ header files to monkey2 externs, and it turned out to be way easier than I thought!

Libclang is a helper lib for the clang c/c++ compilers that provides a simple interface for walking the nodes of an app’s syntax tree. The idea with a c->mx2 convertor is simply to rewrite these nodes into equivalent mx2 ‘extern’ decls.

I did try this a while back but just couldn’t llvm/libclang building from source. This time around, I installed the binaries in the vague hope that libclang might be included – and it is! I don’t think it used to be…but anyway, this made things a lot easier.

And the actual libclang library itself is very nice and clean and easy to use – well, it would be if it weren’t for the fact it’s dealing with c/c++ which has a ton of weird wrinkles.

I’ve managed to use it to put together a little ‘c2mx2’ app (now added to ‘src’ dir) that seems to work pretty well. I’ve used it to convert the chipmunk 2d physics lib API (now a new module), SQLite (also a new module) and a few others. I’ll probably redo the SDL2  API and others too once it’s a bit more tested. It can also convert the ‘libclang’ API itself.

Note that libraries converted this way are still really c/c++ libraries – you still have to deal with pointers and a certain degree of krust. But it makes an excellent starting point for monkey2-ification without having to get your hands too dirty with c/c++ etc. And in the case of nice APIs like chipmunk, it’s still very usable ‘as is’.

There are also things you need to be careful of – in particular, c2mx2 will generate function pointers but these are ‘plain’ C function pointers and should only be used with global functions, not methods or lambdas, otherwise you’ll probably get a bunch of ugly c++ errors when building. More work required here…

Another thing I’ve done in the process (which may affect some native code) is streamline the CString system. In terms of native string types, there is now only CString. Utf8String has gone. Ditto String.FromUtf8String/ToUtf8String have gone.

String.FromCString() now assumes utf8 (falling back to ‘byte per char’ if utf8 is invalid) and String.ToCString() now emits utf8. This just simplifies so many things, esp. with native code where it’s not always clear what encoding const char *’s are, and utf8 is so prevalent now that I think it’s worth the loss of some dubious/confusing extra functionality (that can go elsewhere if necessary) to simplify things significantly.

I will be (re)adding String.FromChars() with arrays/pointers of ints for situations where you want to create strings directly from chars, but as far as CString goes, it’s utf8 all the way.

Finally, you can now return CStrings from extern functions and store them in extern vars/fields, so no more “String.FromCString( SDL_GetError() )” style – SDL_GetError can now return a CString which will be automatically converted to a monkey2 String.


User comments
Difference says:

Thanks. C2mx2 sounds cool.

Great work on the strings, and extended character issues. I think going with UTF8  is a good choice.

Ethernaut says:

That’s exciting, thanks Mark! Do you think the conversion process is simple enough that a non C++ user could handle it? I don’t really know what “you still have to deal with pointers” really means in practice.