1

I have the following code in C++ (Cocos2d) :

typedef void (CCObject::*SEL_CallFunc)();
CCCallFunc * CCCallFunc::actionWithTarget(CCObject* pSelectorTarget,
    SEL_CallFunc selector) {
    CCCallFunc *pRet = new CCCallFunc();

    if (pRet && pRet->initWithTarget(pSelectorTarget)) {
        pRet->m_pCallFunc = selector;
        pRet->autorelease();
        return pRet;
    }

    CC_SAFE_DELETE(pRet);
    return NULL;
}

When converting with swig to java I get the following :

public static CCCallFunc actionWithTarget(CCObject pSelectorTarget, SWIGTYPE_m_CCObject__f___void selector) {
    long cPtr = cocos2dxMappingJNI.CCCallFunc_actionWithTarget(CCObject.getCPtr(pSelectorTarget), pSelectorTarget,
            SWIGTYPE_m_CCObject__f___void.getCMemberPtr(selector));
    return (cPtr == 0) ? null : new CCCallFunc(cPtr, false);
}

Where SWIGTYPE_m_CCObject__f___void is just a pointer I can't use.

How do I implement this in the SWIG interface ? I've looked into this solution stackoverflow but couldn't implement it for my case.

Community
  • 1
  • 1
Driss Bounouar
  • 3,182
  • 2
  • 32
  • 49

2 Answers2

4

I don't believe SWIG supports member function pointers in any meaningful way. However, it's possible to get it done with JavaCPP. Given this C++ code in a file named MemberFunction.h:

class MyClass {
public:
    virtual ~MyClass() { }
};

typedef void (MyClass::*MyFunction)(const char *str);

void callback(MyClass* cls, MyFunction fct, const char *str) {
    (cls->*fct)(str);
}

We can define and use the callback this way in Java:

import org.bytedeco.javacpp.*;
import org.bytedeco.javacpp.annotation.*;

@Platform(include="MemberFunction.h")
public class MemberFunction {
    static { Loader.load(); }

    public static abstract class MyClass extends Pointer {
        public MyClass() { allocate(); }
        private native void allocate();

        @Virtual public abstract void myCallback(String str);

        @Virtual @MemberGetter @Name("myCallback") 
        public static native MyFunction getMyCallback();
    }

    @Namespace("MyClass")
    public static class MyFunction extends FunctionPointer {
        public native void call(MyClass cls, String str);
    }

    public static native void callback(MyClass cls, MyFunction fct, String str);

    public static void main(String[] args) {
        MyClass cls = new MyClass() {
            public void myCallback(String str) { 
                System.out.println(str);
            }
        };
        MyFunction fct = MyClass.getMyCallback();
        callback(cls, fct, "Hello World");
    }
}

Which builds fine and outputs the expected result:

$ javac -cp javacpp.jar MemberFunction.java
$ java -jar javacpp.jar MemberFunction
$ java  -cp javacpp.jar MemberFunction
Hello World
Samuel Audet
  • 4,964
  • 1
  • 26
  • 33
  • I read a lot about JavaCPP, it's honestly fitting our needs, it's just the team started working with SWIG and we already convert millions of code.. we can't switch in that simplicity. So i'm looking for a SWIG solution. – Driss Bounouar Sep 22 '14 at 10:57
1

You probably want to look at a typemap for "SEL_CallFunc selector". The typemap squirrels the original language callback, which is called via a tramploline function. There are python examples here and here. You'll find various similar questions for java on SO.

Community
  • 1
  • 1
John Jefferies
  • 1,176
  • 7
  • 13