Скомпилируйте rxcpp для Android
Я загружаю RxCpp из github, изменяю CMakeLists.txt следующим образом (я использую CMake, модифицированный Microsoft для создания кроссплатформенного проекта с VS2015):
cmake_minimum_required (VERSION 3.4)
project(RxCppAndroid VERSION 2.2.4 LANGUAGES C CXX)
file(GLOB_RECURSE SOURCES "rxcpp/*.*")
# Grouping all the source files puts them into a virtual folder in Visual Studio
source_group("src" FILES ${SOURCES})
add_library(RxCppAndroid SHARED ${SOURCES})
SET_TARGET_PROPERTIES(RxCppAndroid PROPERTIES LINKER_LANGUAGE CXX)
# optional, demo of the VC_MDD_ANDROID* properties
set_property(TARGET RxCppAndroid PROPERTY VC_MDD_ANDROID_USE_OF_STL "c++_static")
set_property(TARGET RxCppAndroid PROPERTY VC_MDD_ANDROID_API_LEVEL "android-21")
Создал решение Project.sln с помощью следующей команды:
cmake -G “Visual Studio 14 ARM” –DCMAKE_SYSTEM_NAME=VCMDDAndroid
Я немного подправил проект, собранный CMake, чтобы:
- включить поддержку C++11
- включить исключения
- Использование STL: статическая библиотека GNU STL (gnustl_static)
Я добавил простой файл cpp со следующим кодом:
#include "rx.hpp"
int test()
{
auto keys = rxcpp::observable<>::create<int>(
[](rx::subscriber<int> dest) {
for (;;) {
int key = std::cin.get();
dest.on_next(key);
}
}).
publish();
}
Проект не компилируется и выдает сотни ошибок. Если я просто попытаюсь скомпилировать только с этой строкой:
#include "rx.hpp"
все отлично работает Если я сделаю
rxcpp::....
intellisense, кажется, просто распознает несколько методов (не так много). Мне не ясно, что происходит. Я застрял. У кого-нибудь есть предложения, что попробовать? У кого-нибудь есть успех при компиляции RxCpp для Android?
// ОБНОВЛЕНИЕ - 03-01-2016
После некоторого анализа выясняется, что большинство сообщений об ошибках были не ошибками компиляции, а связаны с ошибками intellisense. Так что сейчас библиотека успешно скомпилирована. Я установил простое приложение Xamarin, которое использует простую функцию C++ следующим образом:
//C++
#include "rx.hpp"
int test()
{
auto keys = rxcpp::observable<>::create<int>([](rxcpp::subscriber<int> dest)
{
dest.on_next(5);
}).
publish();
//keys.subscribe([](int key)
//{
// int a = key;
//});
return 0;
}
extern "C"
{
int test2()
{
return 5;
}
}
//C#
[DllImport("libTest.so")]
public extern static int test2();
var res=test2();
Если я скомпилировал и развернул на телефоне, все работает нормально (даже думал, что "реактивный" код не используется...). Проблема в том, когда я раскомментирую следующие строки:
keys.subscribe([](int key)
{
int a = key;
});
Затем программа прекрасно компилируется (без ошибок), генерируется libTest.so (размер почти вдвое превышает версию с закомментированной строкой), но как только вызывается функция Test2(), я получаю:
System.DllNotFOundException: libTest.so
Я проверил с adb.exe и действительно libTest.so присутствует в: /data/data/"имя_пакета"/lib/
В чем дело?
// ОБНОВЛЕНИЕ - 06-01-2016
Наконец-то я нашел время для подготовки репозитория, который воспроизводит проблему:
https://github.com/easysoft2k15/AndroidRxCppTest.git
Я подозреваю, что по каким-то причинам, когда я включаю строку, которая вызывает сбой приложения, размер.so lib увеличивается до определенного предела, и, таким образом, Android больше не загружает его. Ваши мысли будут высоко оценены.
Благодарю вас
Alessandro
1 ответ
Благодаря репродукции и проблеме, о которой сообщил Алессандро, я смог найти обходной путь!
По-видимому, поддержка std lib для tls исключена на Android и iOS. Ранее кто-то предлагал поддержку pthread для rxcpp на iOS. Обходной путь должен добавить:
#define RXCPP_ON_IOS
перед включением rx.hpp
или установить -DRXCPP_ON_IOS
флаг на компиляторе.
Исправление будет представлять собой пул-запрос, который изменяет поддержку pthread для работы как на Android, так и на iOS.