kiwibonga
kiwibonga

Reputation: 587

Running C# code from C++ application (Android NDK) for free

I have a C++ game engine that currently supports Windows, Linux and Android (NDK). It's built on top of SDL and uses OpenGL for rendering.

One of the design constraints of this game engine is that the cost of development must be $0.00 -- building the engine should come at no cost to me (other than man hours), I must be allowed to freely redistribute the engine's code and binaries, and users should be able to sell games created using the engine with no restrictions.

Right now, I'm using a very slow interpreted scripting language for game logic -- it actually works well for writing glue code and simple responses to UI events, but not much else.

I'd like to replace this system with a C# solution -- have the user compile a C# class library (DLL) containing their game logic, and have the C++ side 'consume' this DLL and call the appropriate hooks.

It's been rather difficult to find information on how to achieve this in a cross-platform way. Each platform has a different way of hosting the needed runtimes. Also, most articles I've found suggest the use of full-fledged frameworks that provide platform abstractions that are already implemented in my engine.

Is there currently a way to run code from a C# DLL from an Android NDK-based C++ application without using an entirely different SDK, and without having to shell out hundreds of dollars for a license?

In particular, I'm eyeing some of Microsoft's recent open source .net initiatives -- anything there I could use?

EDIT: To clarify, Windows and Linux have well-documented ways of running .net code 'for free' -- this question pertains specifically to calling managed code from an Android NDK application WITHOUT paying licensing fees to Xamarin or another vendor.

Upvotes: 15

Views: 2132

Answers (3)

Michael Anderson
Michael Anderson

Reputation: 73510

The simple answer is no, what you're looking for does not currently exist. You will need to drop/change requirements to find a solution.

The closest I know of is dot42 - which seems to support some of .net on android has recently been put on github and the main site shut-down - but there's no mention of license in the main compiler repository (I've added a bug to get that updated..)

It's not clear that it supports dynamic loading of C# .dll's though as it claims to compile to DEX. (But it may be free, depending on what the developers release as the license...)

Xamarin is the only other feasible alternative that I know of, but as you're aware only the starter edition is free.

If what you're after is purely better scripting support, I'd drop the compiled and C# requirements and find something that works well on android already. Lua is my go to solution for this kind of thing, but I've not used it on android before... and many other options exist.

Upvotes: 2

SomeCallMeTim
SomeCallMeTim

Reputation: 4792

A popular script engine for games is Lua; you might consider using that, since it's trivially easy to link with C/C++. If you use LuaJIT, it's also blazing fast on Android (and not shabby on iOS).

One alternative to consider is that if you build your custom engine on top of Cocos2d-X, you'd not only get Lua (or JavaScript) for free as a connected scripting engine, you'd also get portability to Windows (Win32 and Windows 8.1 Universal), iOS, Mac, and Linux, an IDE (!!), and a huge supportive community.

Or you can spend a lot of time figuring out how to integrate C# into your engine.

Upvotes: 2

jww
jww

Reputation: 102296

It's been rather difficult to find information on how to achieve this in a cross-platform way...

I'm only going to address the issue of "write once, run everywhere."

I build and maintain a library, composed of a single set of sources, that runs on Windows, Linux, OS X, Windows Phone, Android and iOS. To do that, I had to write everything in portable C/C++, and then build DLLs or shared objects.

The project uses .Net interop to call into the DLL, and Android uses JNI to call into the shared object. On iOS a static library is created rather than a shared object.

The DLL or shared object does have some platform specific defines. For example, it must know how to get random numbers from the underlying OS. So it will have a function like:

bool GetRandomNumbers(unsigned char* ptr, size_t size)
{
#if defined(WIN32) || defined(WIN64)
   ...
#elif defined(__linux___) || defined(linux)
   ...
#elif defined(__ANDROID___)
   ...
#endif
}

So keep your core business logic portable and in a DLL or shared object, #define where you must to abstract platform differences, and you will be OK.

On top of the portable library, you layer the platform specific GUI stuff.

If you try to write this in C# and then use that on other platforms, you're just going to be causing yourself problems. The only way to do portability with a single set of sources is to use portable C/C++.

I've also seen folks re-implement in every language: C and Win32 for Windows, .Net for Windows, C for Linux, Cocoa for OS X, .Net for Windows Phone, Java for Android and CocoaTouch for iOS. That creates about 6x the work, and the behaviors are never quite the same across platforms.

Upvotes: 2

Related Questions