简体   繁体   English

将C ++回调转换为Java

[英]Convert a C++ callback to Java

I have the following code in C++ (Cocos2d) : 我在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 : 用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);
}

Where SWIGTYPE_m_CCObject__f___void is just a pointer I can't use. SWIGTYPE_m_CCObject__f___void只是我不能使用的指针。

How do I implement this in the SWIG interface ? 如何在SWIG界面中实现此功能? I've looked into this solution stackoverflow but couldn't implement it for my case. 我已经研究了这个解决方案stackoverflow,但是无法针对我的情况实施它。

I don't believe SWIG supports member function pointers in any meaningful way. 我不认为SWIG以任何有意义的方式支持成员函数指针。 However, it's possible to get it done with JavaCPP . 但是,可以使用JavaCPP完成它。 Given this C++ code in a file named MemberFunction.h : 在名为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);
}

We can define and use the callback this way in Java: 我们可以在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

You probably want to look at a typemap for "SEL_CallFunc selector". 您可能想要查看“ SEL_CallFunc选择器”的类型映射。 The typemap squirrels the original language callback, which is called via a tramploline function. 该类型图使原始语言回调更为松脆,该回调通过tramploline函数调用。 There are python examples here and here . 这里这里都有python示例。 You'll find various similar questions for java on SO. 您将在SO上找到有关Java的各种类似问题。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM