可能性の重複:
SWIG Java Retaining Class information of the objects bouncing from C++ガブガブ飲むJavaは多型のコールバック関数
質問: その型を失うオブジェクトswigged私のC++が渡されるのはなぜJavaのコールバック関数?
セットアップ: 私は、コールバックを行うためガブガブ飲むJavaの例をとると、コールバックrun(Parent p)
に渡されるオブジェクトを追加しました。コールバックは期待どおりに機能しますが、Child
オブジェクトを渡すと、Javaはその型を失い、Child
のときにはParent
と考えられます。これはSwig java callback exampleに基づいています。
システム情報:/ガブガブ飲む1.3.33 のUbuntu 8.04ワット - 影響を与えなかった - 最新ガブガブ飲むが、私はまた、1.3.39をテストした違いを作っオフのチャンスに。
出力:
bash$ java -Djava.library.path=. runme Adding and calling a normal C++ callback ---------------------------------------- Callback::run(5Child) Callback::~Callback() Adding and calling a Java callback ------------------------------------ JavaCallback.run(Parent) Callback::run(5Child) Callback::~Callback()
あなたは出力で見ることができるように - オブジェクトの型は、子供の実際にある - が、そのJavaクラス名は、親会社である - 間違っている...
の場合あなたはJavaコールバックrun(Parent p)
を見て、私はJavaクラスをフェッチしている場所を見ることができます。そしてJavaは実際にこのオブジェクトがParent
タイプのものだと思います - これをChildにキャストしようとすると、期待どおりにClassCastException
が投げられます。
コード:
/* File : example.i */
%module(directors="1") example
%{
#include "example.h"
%}
%include "std_string.i"
/* turn on director wrapping Callback */
%feature("director") Callback;
%include "example.h"
/* File : example.h */
#include <string>
#include <cstdio>
#include <iostream>
#include <typeinfo>
class Parent {
public:
virtual const char* getName() {
return typeid(*this).name();
}
};
class Child : virtual public Parent {
};
class Callback {
public:
virtual ~Callback() { std::cout << "Callback::~Callback()" << std:: endl; }
virtual void run(Parent& p) { std::cout << "Callback::run(" << p.getName() << ")" << std::endl; }
};
class Caller {
private:
Callback *_callback;
public:
Caller(): _callback(0) {}
~Caller() { delCallback(); }
void delCallback() { delete _callback; _callback = 0; }
void setCallback(Callback *cb) { delCallback(); _callback = cb; }
void call() {
Parent *p = new Child();
if (_callback)
_callback->run(*p);
delete p;
}
};
/* File: runme.java */
public class runme
{
static {
try {
System.loadLibrary("example");
} catch (UnsatisfiedLinkError e) {
System.err.println("Native code library failed to load. See the chapter on Dynamic Linking Problems in the SWIG Java documentation for help.\n" + e);
System.exit(1);
}
}
public static void main(String[] args)
{
System.out.println("Adding and calling a normal C++ callback");
System.out.println("----------------------------------------");
Caller caller = new Caller();
Callback callback = new Callback();
caller.setCallback(callback);
caller.call();
caller.delCallback();
callback = new JavaCallback();
System.out.println();
System.out.println("Adding and calling a Java callback");
System.out.println("------------------------------------");
caller.setCallback(callback);
caller.call();
caller.delCallback();
// Test that a double delete does not occur as the object has already been deleted from the C++ layer.
// Note that the garbage collector can also call the delete() method via the finalizer (callback.finalize())
// at any point after here.
callback.delete();
System.out.println();
System.out.println("java exit");
}
}
class JavaCallback extends Callback
{
public JavaCallback()
{
super();
}
public void run(Parent p)
{
System.out.println("JavaCallback.run("+p.getClass().getSimpleName()+")");
super.run(p);
}
}
# File: Makefile
TOP = ../..
SWIG = $(TOP)/../preinst-swig
CXXSRCS = example.cxx
TARGET = example
INTERFACE = example.i
SWIGOPT =
all:: java
java::
$(MAKE) -f $(TOP)/Makefile CXXSRCS='$(CXXSRCS)' SWIG='$(SWIG)' \
SWIGOPT='$(SWIGOPT)' TARGET='$(TARGET)' INTERFACE='$(INTERFACE)' java_cpp
javac *.java
clean::
$(MAKE) -f $(TOP)/Makefile java_clean
check: all
これはガブガブ飲むのバグかもしれない - しかし、私は、これはC++の型/キャストと私のこと愚かであることを願っています...
任意の考えは次のようになり非常に感謝!