Передача данных между 2 собственными модулями (Android NDK) - PullRequest
3 голосов
/ 24 октября 2011

Вот структура моей программы: - 2 независимых модуля libA и libB, каждый из которых представляет собой одну общую библиотеку libA.so и libB.so - Java-действие, создающее 2 потока thA и thB, каждый из которых вызывает собственные функции JNI из одной библиотеки (вызывающие функции из libA.so и вызывающие функцию thB из libB.so).

Я хочу передать данные нативных типов (о которых Java ничего не знает, содержащие типы, такие как указатели, которые Java не может обработать) между обеими библиотеками, но я не смог найти способ заставить их взаимодействовать.

Для обеих библиотек известно определение нативного типа "typeA", есть ли способ передать объект типа A из libA в libB (предпочтительно без необходимости копировать данные в память виртуальной машины). Передать указатель памяти может быть ??

Спасибо

Ответы [ 2 ]

1 голос
/ 04 июня 2015

Я делаю именно это в приложении, над которым работаю.Я выделяю память в libA и возвращаю указатель как long до Java через JNI.Затем я вызываю функцию в libB, которая передает указатель вниз, чтобы к нему можно было получить доступ.

Однако у этого наивного подхода есть проблемы.Хотя это может иногда работать, если libA и libB живут на разных страницах ОЗУ, прикосновение к указателю в libB может привести к сбою программы.Причина сбоя может отличаться в зависимости от сборки и запуска, что затрудняет отладку.Еще хуже, если выделенная память частично находится на одной странице ОЗУ, а частично на другой, только когда вы достигнете границы, вы столкнетесь с тем, что находится за ее пределами, и, следовательно, может не сразу обнаружить проблему.Мне удалось убить ОС много раз и выдать любое количество различных ошибок.Если ваши библиотеки маленькие и загружены в соседнюю память, шансы хорошие, все будет в порядке.Родные приложения на Android могут сойти с рук то, чего не могут ванильные Java-приложения.

Решения:

  1. Ashmem позволитвам создать пространство общей памяти между приложениями.Если вы новичок в разработке для Android или в ОС Linux, то это может привести к обучению.

  2. Вы можете использовать Socket между двумя приложениями и выполнять потоковую передачу данных.

  3. Вы можете отправлять данные из libA через функции JNI напрямую в созданный Java буфер, размер которого должен соответствовать размерам данных из libA.Затем вы могли бы еще раз передать его через JNI в libB.Это решение будет медленнее, и стоимость может привести к недействительности причин, по которым вы используете нативный код для начала, но это хороший способ отладки и обнаружения, если ваши проблемы связаны с памятью или присущи логике вашей программы.

0 голосов
/ 24 октября 2011

Передача указателя на тип A от A до B может быть вариантом. Это зависит от жизненного цикла типа А в библиотеках. Убедитесь, что объект typeA не удален в одной библиотеке, пока он используется в другой.

Один из способов передачи указателя - перейти через JNI и использовать jlong ​​/ long для представления указателя.

...