Reputation: 3242
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.
Upvotes: 1
Views: 368
Reputation: 1216
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.
Upvotes: 1
Reputation: 4994
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
Upvotes: 4