C++ swig Java
От: MaxBond Россия  
Дата: 13.12.13 17:00
Оценка:
Доброго времени суток, коллеги!

Очень нужна помощь в использовании 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 и может помочь практическим советом?
swig java c++ ndk android
Re: C++ swig Java
От: A13x США  
Дата: 13.12.13 18:30
Оценка:
Здравствуйте, 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/
Re[2]: C++ swig Java
От: Pavel Dvorkin Россия  
Дата: 15.12.13 05:49
Оценка:
Здравствуйте, A13x, Вы писали:

A>Очевидным способом можно использовать только сишные сущности, использование С++ функциональности (например классов — ну или СОМ интерфейсов) будет предполагать горы glue кода. Если все же хочется использовать СОМ в яве, то для начала советую глубоко изучить jni, C, COM — особенно как последний использовать из С. Простого пути сделать именно то, что вы хотите нет.


+1

Можно (если можно) написать С-wrappper над С++, то есть еще одну DLL , которая внутри себя оперирует С++ классами (ей-то что за проблема), а наружу показывает С-функции, к которым и иметь доступ из Явы.

Кстати, вместо JNI можно использовать JNA

https://github.com/twall/jna
With best regards
Pavel Dvorkin
Re: C++ swig Java
От: Pavel Dvorkin Россия  
Дата: 15.12.13 05:58
Оценка: 3 (1)
Здравствуйте, MaxBond, Вы писали:

Посмотри на всякий случай здесь, может, что-то подберешь.

http://stackoverflow.com/questions/3720563/access-c-shared-library-from-java-jni-jna-cni-or-swig
With best regards
Pavel Dvorkin
Re[2]: C++ swig Java
От: MaxBond Россия  
Дата: 15.12.13 12:39
Оценка:
Здравствуйте, 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++ — очень классное сочетание!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.