从C ++d起的对象的SWIG Java保留类信息

从C ++d起的对象的SWIG Java保留类信息,第1张

从C ++d起的对象的SWIG Java保留类信息

我已经解决了这个问题。但是,这并不是您在问题中建议的解决方案,它在Java方面有更多代码,在JNI / C
++方面没有更多的代码。(我发现这样做的方法很棘手,要想在所有可能的情况下正确无误)。

我将类简化为单个头文件:

class GameObject {};class CollisionListener {public:    virtual bool collidedWith(GameObject &) { return false; }    virtual ~CollisionListener() {} };inline void makeCall(GameObject& o, CollisionListener& c) {    c.collidedWith(o);}

makeCall
实际上使问题变得显而易见。

我使用的技巧是注册所有Java衍生的实例

GameObject
HashMap
自动创建时。然后,在调度Director调用时,这只是在HashMap中查找它的问题。

然后是模块文件:

%module(directors="1") Test%{#include "test.hh"%}%pragma(java) jniclasspre=%{  static {    try {        System.loadLibrary("test");    } catch (UnsatisfiedlinkError e) {      System.err.println("Native pre library failed to load. n" + e);      System.exit(1);    }  }%}// An import for the hashmap type%typemap(javaimports) GameObject %{import java.util.HashMap;import java.lang.ref.WeakReference;%}// Provide a static hashmap, // replace the constructor to add to it for derived Java types%typemap(javabody) GameObject %{  private static HashMap<Long, WeakReference<$javaclassname>> instances   = new HashMap<Long, WeakReference<$javaclassname>>();  private long swigCPtr;  protected boolean swigCMemOwn;  public $javaclassname(long cPtr, boolean cMemoryOwn) {    swigCMemOwn = cMemoryOwn;    swigCPtr = cPtr;    // If derived add it.    if (getClass() != $javaclassname.class) {      instances.put(swigCPtr, new WeakReference<$javaclassname>(this));    }  }  // Just the default one  public static long getCPtr($javaclassname obj) {    return (obj == null) ? 0 : obj.swigCPtr;  }  // Helper function that looks up given a pointer and   // either creates or returns it  static $javaclassname createOrLookup(long arg) {    if (instances.containsKey(arg)) {      return instances.get(arg).get();    }    return new $javaclassname(arg,false);  }%}// Remove from the map when we release the C++ memory%typemap(javadestruct, methodname="delete",          methodmodifiers="public synchronized") GameObject {  if (swigCPtr != 0) {    // Unregister instance    instances.remove(swigCPtr);    if (swigCMemOwn) {      swigCMemOwn = false;      $imclassname.delete_GameObject(swigCPtr);    }    swigCPtr = 0;  }}// Tell SWIG to use the createOrLookup function in director calls.%typemap(javadirectorin) GameObject& %{    $javaclassname.createOrLookup($jniinput)%}%feature("director") GameObject;// Finally enable director for CollisionListener and include the header%feature("director") CollisionListener;    %include "test.hh"

请注意,由于所有Java实例都存储在中,因此

HashMap
我们需要使用a
WeakReference
来确保我们不会延长其寿命并防止发生垃圾收集。如果您在乎线程,则在适当时添加同步。

我用以下方法对此进行了测试:

public class main {  public static void main(String[] argv) {    JCollisionListener c = new JCollisionListener();    JGameObject o = new JGameObject();    c.collidedWith(o);      Test.makeCall(o,c);  }}

哪里

JCollisionListener
是:

public class JCollisionListener extends CollisionListener {  public boolean collidedWith(GameObject i) {    System.out.println("In collide");    if (i instanceof JGameObject) {       System.out.println("Is J");    }    else {       System.out.println("Not j");    }    JGameObject o = (JGameObject)i;    return false;  }}

并且

JGameObject
是:

public class JGameObject extends GameObject {}

(作为参考,如果您想使用其他方法,您将在编写类型

directorin
映射时进行查看)。



欢迎分享,转载请注明来源:内存溢出

原文地址: http://outofmemory.cn/zaji/5499630.html

(0)
打赏 微信扫一扫 微信扫一扫 支付宝扫一扫 支付宝扫一扫
上一篇 2022-12-12
下一篇 2022-12-12

发表评论

登录后才能评论

评论列表(0条)

保存