I was original interested in AllJoyn because it looked like a good way to build local multiplayer mobile games. At one point a few years back they even provided a Unity3D library. I got a simple "hello world" app working on PC/iOS/Android, but then got busy with other things and the project was eventually cancelled.

I've been thinking about it again and looking at ways of getting it into .Net applications. Unfortunately they no longer provide the Unity library which would have given me a good start.

Ran into some issues with their Linux build instructions. apt-get didn't want to install ia32-libs since I already had ncurses installed. Next, the src zip directory structure didn't quite match what's in the documentation (I guess they want you to move directories around). But you can just run scons from the root of the decompressed source code. I got a compile error about not being able to find sys/capability.h. apt-get had given up ia32-libs and didn't install libcap-dev. Once I got that everything seemed to work.

Basically, I ended up doing:


sudo apt-get install build-essential libgtk2.0-dev libssl-dev xsltproc libxml2-dev libcap-dev python scons libssl-dev
scons BINDINGS=cpp WS=off BT=off ICE=off SERVICES="about"

You can verify everything works by running the sample app. On a 64-bit system scons seems to build for x86_64 by default.

In one shell:

  1. export LD_LIBRARY_PATH=`pwd`/build/linux/x86_64/debug/dist/cpp/lib:$LD_LIBRARY_PATH
  2. build/linux/x86_64/debug/dist/cpp/bin/samples/basic_service
And in another:
  1. export LD_LIBRARY_PATH=`pwd`/build/linux/x86_64/debug/dist/cpp/lib:$LD_LIBRARY_PATH
  2. build/linux/x86_64/debug/dist/cpp/bin/samples/basic_client
Now I've got the native AllJoyn library, but I still need to get it working with .Net. SWIG is my first thought to do this. PInvoke Interop Assistant is potentially another option, but it looks like it hasn't been developed for some time. Following the SWIG tutorial I created the interface file alljoyn.swig specifying header files included by samples/basic/basic_client.cc:

%module alljoyn
%{
/* Includes the header in the wrapper code */
#include "alljoyn_core/inc/alljoyn/AllJoynStd.h"
#include "alljoyn_core/inc/alljoyn/BusAttachment.h"
#include "build/linux/x86_64/debug/dist/cpp/inc/alljoyn/Status.h"
#include "alljoyn_core/inc/alljoyn/Init.h"
#include "alljoyn_core/inc/alljoyn/version.h"

// Needed for alljoyn_wrap.cxx to compile
using namespace qcc;
using namespace ajn;
%}

/* Parse the header file to generate wrappers */
%include "alljoyn_core/inc/alljoyn/AllJoynStd.h"
%include "alljoyn_core/inc/alljoyn/BusAttachment.h"
%include "build/linux/x86_64/debug/dist/cpp/inc/alljoyn/Status.h"
%include "alljoyn_core/inc/alljoyn/Init.h"
%include "alljoyn_core/inc/alljoyn/version.h"
Then build everything:

mkdir alljoyn_cs
cd alljoyn_cs
# Create alljoyn.swig here

# Generate SWIG wrapper code
swig -c++ -csharp -cpperraswarn alljoyn.swig

# Build shared lib
g++ -fPIC -c -DQCC_OS_GROUP_POSIX -I../build/linux/x86_64/debug/dist/cpp/inc -I../alljoyn_core/inc -I../common/inc alljoyn_wrap.cxx
g++ -shared -L../build/linux/x86_64/debug/dist/cpp/lib -o liballjoyn.so alljoyn_wrap.o -lajrouter -Wl,-Bstatic -lalljoyn -Wl,-Bdynamic -lssl -lcrypto

# Update so mono can find liballjoyn.so
export LD_LIBRARY_PATH=`pwd`:$LD_LIBRARY_PATH
I included all the swig generated csharp source files into a MonoDevelop project, and you can now call simple AllJoyn functions from C#:

if (alljoyn.AllJoynInit () != QStatus.ER_OK)
return;

Console.WriteLine ("AllJoyn Library version: {0}", alljoyn.GetVersion ());
Console.WriteLine ("AllJoyn Library build info: {0}", alljoyn.GetBuildInfo ());

var status = QStatus.ER_OK;

var msgBus = new BusAttachment ("myApp", true);
if (msgBus == null)
status = QStatus.ER_OUT_OF_MEMORY;
That's a good start, but I've run into a problem. As expected, swig doesn't always generate "natural" c# code. BusAttachment.CreateInterface() has the following signature:

public QStatus CreateInterface(string name, SWIGTYPE_p_p_InterfaceDescription iface)
Where SWIGTYPE_p_p_InterfaceDescription is some pointer wrapper for the managed/unmanaged magic that swig generated for us rather than something like "out InterfaceDescription". It looks like swig provides typemaps to solve these sorts of problems, but in any case I'm not quite done yet. Misc other docs that were helpful: