Доброго времени суток, коллеги!
Очень нужна помощь в использовании 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 и может помочь практическим советом?
Здравствуйте, MaxBond, Вы писали:
MB>Доброго времени суток, коллеги!
MB>Очень нужна помощь в использовании swig в рамках JNI под Android.
MB>Имеется с++ библиотека, которую необходимо использовать в Java-приложении.
MB>С++ интерфейс данной библиотеки аналогичен COM-интерфейсам — имеется базовый ссылочный тип IReference (аналог IUnknown в COM)
MB>и фабричная функция QueryInterface(const char* guid), которая по guid возвращает(создает) указатель на интерфейс нужного типа, приведенный к базовому IReference
MB>[ccode]
MB>...
Очевидным способом можно использовать только сишные сущности, использование С++ функциональности (например классов — ну или СОМ интерфейсов) будет предполагать горы glue кода. Если все же хочется использовать СОМ в яве, то для начала советую глубоко изучить jni, C, COM — особенно как последний использовать из С. Простого пути сделать именно то, что вы хотите нет.
COM in plain C:
http://www.codeproject.com/Articles/13601/COM-in-plain-C
JNI:
http://docs.oracle.com/javase/6/docs/technotes/guides/jni/
Здравствуйте, A13x, Вы писали:
A>Очевидным способом можно использовать только сишные сущности, использование С++ функциональности (например классов — ну или СОМ интерфейсов) будет предполагать горы glue кода. Если все же хочется использовать СОМ в яве, то для начала советую глубоко изучить jni, C, COM — особенно как последний использовать из С. Простого пути сделать именно то, что вы хотите нет.
+1
Можно (если можно) написать С-wrappper над С++, то есть еще одну DLL , которая внутри себя оперирует С++ классами (ей-то что за проблема), а наружу показывает С-функции, к которым и иметь доступ из Явы.
Кстати, вместо JNI можно использовать JNA
https://github.com/twall/jna
Здравствуйте, Pavel Dvorkin, Вы писали:
PD>Здравствуйте, MaxBond, Вы писали:
PD>Посмотри на всякий случай здесь, может, что-то подберешь.
PD>http://stackoverflow.com/questions/3720563/access-c-shared-library-from-java-jni-jna-cni-or-swig
Друзья, спасибо за содействие.
С вашей поддержкой успешно разобрался в интересующем вопросе.
Swig — в топку!
Помогла статья:
http://idev.by/android/22971/
Проще все написать своими руками.
Java + JNI + C++ — очень классное сочетание!