将C++回调转换为Java

Convert a C++ callback to Java

本文关键字:Java 转换 回调 C++      更新时间:2023-10-16

我在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;
}

当用swig转换为java时,我得到以下内容:

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);
}

其中SWIGTYPE_m_CCObject__f___void只是一个我不能使用的指针。

如何在SWIG接口中实现此功能?我已经研究了这个stackoverflow解决方案,但无法为我的案例实现它。

我不认为SWIG以任何有意义的方式支持成员函数指针。但是,使用JavaCPP可以完成这项工作。在名为MemberFunction.h:的文件中给定此C++代码

class MyClass {
public:
    virtual ~MyClass() { }
};
typedef void (MyClass::*MyFunction)(const char *str);
void callback(MyClass* cls, MyFunction fct, const char *str) {
    (cls->*fct)(str);
}

我们可以在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");
    }
}

构建良好并输出预期结果的

$ javac -cp javacpp.jar MemberFunction.java
$ java -jar javacpp.jar MemberFunction
$ java  -cp javacpp.jar MemberFunction
Hello World

您可能想要查看"SEL_CallFunc选择器"的类型映射。typemap通过蹦床函数调用原始语言回调。这里和这里都有python的例子。在SO.

上,您会发现各种类似的java问题