Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Is it possible to add C references to an objective c binding?

There are some C style functions in an Objective C library I'm binding to that I need access to in my application. Is it possible to add these into the bindings in any way so I can access them in my C# application?

EXAMPLE from Cocos2d:

void ccGLActiveTexture( GLenum textureEnum )
{
#if CC_ENABLE_GL_STATE_CACHE
    NSCAssert1( (textureEnum - GL_TEXTURE0) < kCCMaxActiveTexture, @"cocos2d ERROR: Increase kCCMaxActiveTexture to %d!", (textureEnum-GL_TEXTURE0) );
    if( (textureEnum - GL_TEXTURE0) != _ccCurrentActiveTexture ) {
        _ccCurrentActiveTexture = (textureEnum - GL_TEXTURE0);
        glActiveTexture( textureEnum );
    }
#else
    glActiveTexture( textureEnum );
#endif
}

EDIT

Link to header with functions I'm trying to import: http://www.cocos2d-iphone.org/api-ref/2.0.0/cc_g_l_state_cache_8h_source.html

I tried this in my Extras.cs

public partial class CCGLProgram {
[DllImport("__Internal")]
    public static extern void ccGLUseProgram( uint program );

    public static void CCGLUseProgram(uint test)
    {
        ccGLUseProgram(test);
    }
}

Unfortunately, I get an entry point not found error. I guess my first thought is maybe the function is mangled but I thought since the 'extern C' is there that shouldn't be happening? Can anyone help me?

like image 357
AwDogsGo2Heaven Avatar asked Jan 06 '13 04:01

AwDogsGo2Heaven


1 Answers

You can add classic .NET p/invokes, [DllImport], for any additional C API you need. They can be added to your binding assembly easily as doing bindings is a two step process.

First your API definitions (interfaces) are compiled, along with extra definitions (e.g. enums) into a temporary assembly.

Next that assembly is then used to generate code (using btouch): the bindings you'll use. It's possible to include more code, like the p/invokes, at that stage so they will be part of your final, compiled, binding assembly.

Trick: There's a lot of samples available in GIT's monotouch-bindings, just grep around for DllImport and you'll find some.

EDIT (2013-01-08)

There's something wrong with the Release build (even if it simply calls xcodebuild) done by the Makefile since it works when I rebuild libcocos2d.a in debug. E.g.

cd monotouch-bindings/cocos2d/binding
make debug

To test this I added your code (a bit simplified) into the existing extra.cs:

public partial class CCGLProgram {
    [DllImport ("__Internal", EntryPoint="ccGLUseProgram")]
    public static extern void UseProgram (uint program);
}

and added a call to CCGLProgram.UseProgram (0); from inside the FinishedLaunching method of the Jumpy demo app.

EDIT (2013-01-12)

The debug and release builds are quite similar (not surprising). The debug build has a few debug related defines (again not surprising). OTOH the release build is done with -fvisibility=hidden which (I need to validate this later) sounds like a good candidate for this issue.

It's indeed a (non default, see last column) build setting in the Xcode project. Changing this settings to No (which is normally the default) will produce a Release build where you can use normal [DllImport] (like above) to call the C functions. Mystery solved :-)

Xcode settings

EDIT (2013-01-13)

This change is now handled in MonoTouch's bindings Makefile, i.e. rebulding your Cocos2d.dll assembly (do both a make clean and make clean all to remove the managed and native code) will solve this automagically. Have fun!

like image 77
poupou Avatar answered Sep 18 '22 14:09

poupou