Ok, có một từ khóa mà tôi đã cố tình tránh xa các thẻ và tiêu đề. Đó là "Android", nhưng đó là bởi vì mặc dù dự án là trong Android, tôi không nghĩ rằng câu hỏi của tôi có liên quan gì đến nó, và tôi không muốn dọa mọi người mà không có kinh nghiệm trong Android.SWIG Java giữ lại thông tin lớp của các đối tượng nảy từ C + +
Vì vậy, vấn đề thường gặp với swig. Tôi đã có một phương pháp ảo trong một lớp C++, mà tôi đã làm cho nó quá tải trong Java bằng cách thêm các tính năng director
cho lớp và nó hoạt động. Vấn đề là phương thức nhận được một đối số đa hình cũng được mở rộng ở phía java, và trong khi gọi phương thức ảo trong Java, đối tượng đi kèm với tất cả các thông tin đa hình bị tước bỏ.
Để trình bày tình hình chính xác; Tôi đang viết một công cụ trò chơi trong C++ và tôi muốn sử dụng nó một cách vui vẻ trong Java. Công cụ trò chơi có lớp GameObject
, đăng ký CollisionListener
s và khi động cơ va chạm phát hiện sự kiện va chạm, nó gọi phương thức collidedWith(GameObject & collidee)
của tất cả các đăng ký collisionListener
s truyền chúng với đối tượng mà chúng đã va chạm.
class CollisionListener {
public:
virtual bool collidedWith(GameObject &){};
~CollisionListener(){} // I know this needs to be virtual but let's forget about that now
};
Tôi đang phơi bày lớp này, cùng với các lớp GameObject
để java bằng cách sử dụng tập tin giao diện sau Bridge.i
%module(directors="1") Bridge
%feature("director") CollisionListener;
%include "CollisionListener";
%feature("director") GameObject;
%include "GameObject.h"
Bây giờ, khi tôi kế thừa từ CollisionListener
trong java và quá tải collidedWith
, nó lấy được gọi là với một đối tượng java GameObject
. Ví dụ, nếu tôi kế thừa từ lớp java GameObject
và xác định một lớp Bullet
, khi viên đạn này va chạm với một đối tượng khác với một người nghe, trong cuộc gọi phương thức collidedWith
, tất cả tôi nhận được là GameObject
, để (object instanceof Bullet)
không hoạt động. Không ngạc nhiên, tôi đã đào vào uống một lân tạo BridgeJNI.java
và thấy điều này:
public static boolean SwigDirector_CollisionListener_collidedWith(CollisionListener self, long arg0) {
return self.collidedWith(new GameObject(arg0, false));
}
Vì vậy, nó kết thúc tốt đẹp một đối tượng mới xung quanh con trỏ trước khi gọi quá tải java.
Vì vậy, câu hỏi chính là cách nhận đối tượng Bullet
khi có xung đột?
Tôi đã tìm ra cách dễ dàng đạt được điều đó nhưng tôi cần sửa đổi các tệp được tạo tự động, đó là một ý tưởng tồi. Vì vậy, tôi hy vọng một số chủ swig có thể giúp tôi tiêm các sửa đổi để các tập tin tạo ra swig.
Hack nhỏ của tôi là giữ jobject * self
trong mọi đối tượng bên cạnh C++ GameObject
và gán địa chỉ của đối tượng java thực trong khi xây dựng mặt java thực GameObject
(và không phải chỉ đơn thuần là kết thúc con trỏ). Bằng cách này, tôi có thể định nghĩa một phương pháp đa hình getSelf
ở bên C++ GameObject
và sử dụng kết quả một cách vui vẻ trong java. Có cách nào để tiêm mã cần thiết để các tập tin tạo ra swig?
Cảm ơn
Lưu ý: Nếu bạn đã thử đạo diễn trên Android và họ chưa làm việc, đó là vì phiên bản ổn định hiện tại không hỗ trợ. Tải xuống Bleeding Edge từ trang web swig. Nhưng tôi đang viết điều này vào ngày 22/03/2012 và ghi chú này sẽ sớm không cần thiết. Lý do tại sao các destructor không phải là ảo là phiên bản Bleeding Edge làm cho chương trình sụp đổ trong destructor, và làm cho nó không ảo dường như giữ cho nó dưới sự kiểm soát cho bây giờ.
Vì vậy, phiên bản ngắn của câu hỏi là bạn muốn có thể (ví dụ) lấy được 'GameObject' trong Java và vẫn có thể truyền trong Java khi kiểu dẫn xuất đó được chuyển đến thực thi Java 'collidedWith'? Khá chắc chắn hack nhỏ của bạn có thể được bọc trong một typemap nếu đó là trường hợp. – Flexo
Chính xác! Tôi nghĩ rằng swig sẽ có một cách để tiêm mã, nhưng tôi khá mới để swig. Tôi sẽ kiểm tra các bản đồ. – enobayram
Tôi sẽ viết câu trả lời vào ngày mai. – Flexo