Ok, jest słowo kluczowe, które celowo trzymałem z dala od znaczników i tytułu. To "Android", ale to dlatego, że mimo że projekt jest w systemie Android, nie sądzę, że moje pytanie ma z tym coś wspólnego, i nie chcę przestraszyć ludzi bez doświadczenia w systemie Android.SWIG Informacje o klasie zachowania klasy Java obiektów skaczących z C++
Zwykły problem z łykiem. Mam wirtualną metodę w klasie C++, której nadałem w Javie, dodając do klasy funkcję director
i to działa. Problem polega na tym, że metoda otrzymuje polimorficzny argument, który jest również rozszerzony po stronie Java, a podczas wywołania metody wirtualnej w Javie, obiekt jest usuwany z całej informacji polimorficznej.
Aby przedstawić dokładną sytuację; Piszę silnik gry w C++ i chcę go używać na szczęście w Javie. Silnik gry ma klasę GameObject
, która rejestruje CollisionListener
s, a gdy silnik kolizji wykryje zdarzenie kolizyjne, wywołuje metodę collidedWith(GameObject & collidee)
dla wszystkich zarejestrowanych , przekazując im obiekt, który spowodował kolizję.
class CollisionListener {
public:
virtual bool collidedWith(GameObject &){};
~CollisionListener(){} // I know this needs to be virtual but let's forget about that now
};
ja wystawiając tej klasy, wraz z klasą GameObject
Java stosując następujący plik interfejsu Bridge.i
%module(directors="1") Bridge
%feature("director") CollisionListener;
%include "CollisionListener";
%feature("director") GameObject;
%include "GameObject.h"
Teraz, kiedy dziedziczą CollisionListener
w Java i przeciążeniu collidedWith
, to się nazywa z obiektem po stronie Java GameObject
. Na przykład, jeśli dziedziczę po klasie java GameObject
i definiuję klasę Bullet
, gdy ten punkt zderzy się z innym obiektem z detektorem, w wywołaniu metody collidedWith
, wszystko, co otrzymam, to pusty GameObject
, więc (object instanceof Bullet)
nie działa. Nic dziwnego, ja wykutych w SWIG generowane BridgeJNI.java
i stwierdziliśmy:
public static boolean SwigDirector_CollisionListener_collidedWith(CollisionListener self, long arg0) {
return self.collidedWith(new GameObject(arg0, false));
}
Więc to nowy obiekt owija wokół wskaźnika przed wywołaniem przeciążeń Java.
Głównym pytaniem jest zatem, jak otrzymać obiekt Bullet
w przypadku kolizji?
Wymyśliłem sposób, aby łatwo to osiągnąć, ale muszę zmodyfikować automatycznie generowane pliki, co jest złym pomysłem. Mam więc nadzieję, że jakiś swig master pomoże mi wprowadzić modyfikacje plików generowanych przez swig.
Mój mały kilof jest utrzymanie jobject * self
w każdym C++ strona GameObject
obiektu i przypisanie adresu rzeczywistego obiektu java podczas budowy strony GameObject
(a nie jednego, że tylko owija wskaźnik) real java. W ten sposób mógłbym zdefiniować metodę polimorficzną getSelf
w języku C++ po stronie GameObject
i używać wyniku szczęśliwie w java. Czy istnieje sposób na wstrzyknięcie niezbędnego kodu do wygenerowanych plików swig?
Dzięki
Uwaga: Jeśli próbowałeś dyrektorów na Androida i oni nie pracowali, to dlatego, że obecna stabilna wersja nie obsługuje. Pobierz Bleeding Edge ze strony internetowej. Ale piszę to w dniu 22.03.2012 r., A ta notatka wkrótce będzie niepotrzebna. Powodem, dla którego destruktor nie jest wirtualny, jest to, że wersja Bleeding Edge powoduje awarię programu w destruktorze, a sprawienie, że jest ona nie-wirtualna, wydaje się na razie kontrolować.
Skrócona wersja twojego pytania jest taka, że chcesz (na przykład) wyprowadzić 'GameObject' w Javie i nadal móc rzutować w Javie, gdy ten typ pochodny zostanie przekazany do implementacji Java' collidedWith'? Jestem pewien, że twój mały hack może być zawinięty w typografię, jeśli tak jest. – Flexo
Precyzyjnie! Pomyślałem, że łyk będzie miał sposób na wstrzyknięcie kodu, ale jestem całkiem nowy, by łykać. Sprawdzę mapy typów. – enobayram
Zapiszę jutro mam nadzieję. – Flexo