Доброго времени суток, коллеги!
Очень нужна помощь в использовании swig в рамках JNI под Android.
Имеется с++ библиотека, которую необходимо использовать в Java-приложении.
С++ интерфейс данной библиотеки аналогичен COM-интерфейсам — имеется базовый ссылочный тип IReference (аналог IUnknown в COM)
и фабричная функция QueryInterface(const char* guid), которая по guid возвращает(создает) указатель на интерфейс нужного типа, приведенный к базовому IReference
//базовый ссылочный интерфейс
class IReference
{
public:
virtual long AddRef(void)=0;
virtual long ReleaseRef(void)=0;
virtual IReference* QueryInterface(const char* guid)=0;
};
//функция получения фабрики
IReference* GetObjectFactory();
//callback-интерфейс
class IDoneCallback
{
public:
virtual void OnTaskDone(void)=0;
};
//некий производный интерфейс
class IWorker : public IReference
{
public:
virtual int Work(IDoneCallback callback)=0;
};
Т.е., на С++ использование данного API выглядит примерно так
//определяем обработчик
class MyWorkerListener : public IDoneCallback
{
virtual void OnTaskDone(void) { printf("Task done!\n"); }
};
IReference* factory = GetObjectFactory(); //фабрика
//запрашиваем у фабрики нужный интерфейс
IWorker* worker = (IWorker*)factory->QueryInterface("GUID_IWorker");
//освобождаем фабрику
factory->ReleaseRef();
//создаем слушателя
MyWorkerListener listener;
//просим поработать и по завершению получаем вызов IDoneCallback::OnTaskDone()
worker->Work(&listener);
...
//освобождаем объект
worker->ReleaseRef();
Необходимо переложить это на Java, используя swig или ему подобный инструмент.
Я столкнулся со следующими проблемами:
1. Ожидалось увидеть на java аналогичные интерфесы
public interface IReference { ... }
А на деле имеем получаем proxy-class-ы, с конструкторами и деструкторами в виде методов finalize()/delete()
2. Хотелось бы на Java использовать такой код
public class MyWorkerListener implements IDoneCallback {...}
MyWorkerListener listener = new MyWorkerListener();
worker.Work(listener);
но на практике передать и потом вызвать java-интерфейс в C++ не получается.
3. На java имеются проблемы с Downcasting вида:
IWorker worker = (IWorker)factory.QueryInterface("GUID_IWorker");
Для этого нужно написать тучу специального кода, как приведено в офиц документации:
http://www.swig.org/Doc2.0/SWIGDocumentation.html#Java_adding_downcasts
Может быть кто-то сталкивался с задачей переноса подобных С++ интерфейсов на java и может помочь практическим советом?