Сначала я скомпилировал libcurl на своем Mac с помощью следующего скрипта.
ARCH=$1
API_VER="21"
if [ $ARCH == "x86" ]; then
HOST="i686"
DEST_DIR="x86"
elif [ $ARCH == "x86_64" ]; then
HOST="x86_64"
DEST_DIR="x86_64"
elif [ $ARCH == "arm" ]; then
HOST="arm"
DEST_DIR="armeabi-v7a"
elif [ $ARCH == "arm64" ]; then
HOST="aarch64"
DEST_DIR="arm64-v8a"
fi
if [ $HOST == "arm" ]; then
CLANG="armv7a-linux-androideabi$API_VER-clang"
HOST="$HOST-linux-androideabi"
else
CLANG="$HOST-linux-android$API_VER-clang"
HOST="$HOST-linux-android"
fi
NDK_VER="20"
NDK_HOME="/Users/visor24-mac/Android-NDK/android-ndk-r$NDK_VER"
SYSROOT="$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/sysroot"
INCPATH="/Users/visor24-mac/Project/External/prebuilt/include/android/${DEST_DIR}/openssl"
LIBPATH="/Users/visor24-mac/Project/External/prebuilt/lib/android/${DEST_DIR}"
PREFIX="/Users/visor24-mac/Project/External/curl/build/android/$ARCH"
export PATH="$NDK_HOME/toolchains/llvm/prebuilt/darwin-x86_64/bin":"$PATH"
export CC="$CLANG"
export CPPFLAGS="-I${INCPATH}"
export CFLAGS="--sysroot ${SYSROOT} -O3"
export LDFLAGS="-L${LIBPATH} --sysroot ${SYSROOT}"
./configure --disable-shared --enable-static --host=$HOST --prefix=$PREFIX
make -j 4 && make install || exit 2
Затем коды для загрузки URL.
static size_t write_data(void *ptr, size_t size, size_t nmemb, void *stream)
{
size_t written = fwrite(ptr, size, nmemb, (FILE *)stream);
l_info << written;
if ( size * nmemb != written )
l_error;
g_written += written;
return written;
}
static void DownloadURL( const std::string& url, const std::string& fileName )
{
CURL* curlHandle = nullptr;
FILE* file = nullptr;
curl_global_init(CURL_GLOBAL_ALL);
curlHandle = curl_easy_init();
auto rc = curl_easy_setopt( curlHandle, CURLOPT_URL, url.c_str() );
rc = curl_easy_setopt( curlHandle, CURLOPT_VERBOSE, 0L );
rc = curl_easy_setopt( curlHandle, CURLOPT_NOPROGRESS, 1L );
rc = curl_easy_setopt( curlHandle, CURLOPT_SSL_VERIFYHOST, 0L );
rc = curl_easy_setopt( curlHandle, CURLOPT_SSL_VERIFYPEER, 0L );
rc = curl_easy_setopt( curlHandle, CURLOPT_WRITEFUNCTION, write_data );
file = fopen( fileName.c_str(), "wb" );
if ( file )
{
//curl_easy_setopt( curlHandle, CURLOPT_WRITEDATA, stdout );
curl_easy_setopt( curlHandle, CURLOPT_WRITEDATA, file );
rc = curl_easy_perform(curlHandle);
if ( rc != CURLE_OK )
{
l_error << curl_easy_strerror( rc );
}
else
{
l_info << "CURL DOWNLOAD SUCCESS!!!!";
}
fclose( file );
}
curl_easy_cleanup( curlHandle );
curl_global_cleanup();
}
И простой сервер Python.
python3 -m http.server
Все отлично работает, кроме одного случая. libcurl пропускает один байт каждые несколько раз в середине, что приводит к получению короткого файла длиной в несколько байт из оригинала со следующей ошибкой.
Передан частичный файл
Это происходит только в эмулятореработает на Windows и только при загрузке с моего простого сервера Python.
Реальное устройство телефона работает нормально. Эмулятор на Mac работает отлично. Даже эмулятор на Win работает нормально, когда я загружаю случайное веб-содержимое.
Я могу продолжать работать на своем Mac, и это устраняет эту проблему, но это немного раздражает, потому что Windows PC был моей основной машиной для разработки. И мне очень любопытно, что может вызвать это. Как я уже сказал, libcurl скомпилирован на Mac для всех ABI, затем я связал их с моим приложением в Android Studio на моем Win PC. Таким образом, даже если ABI одинаков как для libcurl, так и для моего приложения, кросс-компиляция ОС хоста не будет. Может ли это вызвать проблемы? Есть идеи?