가능한 중복 :
SWIG Java Retaining Class information of the objects bouncing from C++꿀꺽 꿀꺽 자바 다형성 콜백 함수
질문 : 유형을 잃고 객체 swigged 내 C는 + + A를 전달하는 이유 자바 콜백 함수?
설정 : 나는 콜백을 수행하기위한 꿀꺽 꿀꺽 자바 예를 촬영하고 콜백 run(Parent p)
에 전달 될 객체를 추가했습니다. 콜백은 예상대로 작동하지만 Child
객체를 전달하면 Java는 해당 유형을 잃어버린 것처럼 보이고 Child
일 때 Parent
유형을 생각합니다. 이는 Swig java callback example을 기반으로합니다.
시스템 정보 : 우분투 8.04/w 꿀꺽 꿀꺽 1.3.33 - 영향을 미치지 아니 - 최신 꿀꺽 꿀꺽가 나는 또한 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 클래스의 이름은 부모 - 잘못 ...
하는 경우 당신은 자바 콜백 run(Parent p)
을 보면 자바 클래스를 가져 오는 곳을 볼 수 있습니다. 자바는 실제로이 객체가 Parent
유형이라고 생각합니다.이 객체를 자식에게 캐스팅하려고하면 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++ 유형 /와 바보 것을 바라고 있어요 ...
어떤 생각이 될 것이다 대단히 감사합니다!