java jni udt找不到so_移植UDT到Android平台
UDT是UDP Based Data Transfer的縮寫,這是一個基于UDP協議的在應用層實現的一種面向連接的傳輸協議,主要目的是在于支持高速廣域網上的數據海量傳輸。其采用C++開發,具有高度的可移植性,并且開源,你可以在這里下載到UDT的源碼https://sourceforge.net/projects/udt/
在開發者提供的代碼中,包含了UDT的核心代碼和應用例程,并提供了Visual Studio的Windows項目工程和Linux下的Makefile。這里我們將要參考Linux下的makefile并使用Android NDK在Windows下將其移植到Android平臺。
移植步驟:
1.創建一個jni目錄,這里我們使用F:\UDT\jni
2.把下載得到的udt源碼放到jni目錄里,這里就變成了F:\UDT\jni\udt4
3.創建Android.mk文件,內容為
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
APP_STL := gnustl_static
LOCAL_CFLAGS := -DLINUX -fvisibility=hidden
LOCAL_CPP_FEATURES += exceptions
LOCAL_ARM_MODE := arm
LOCAL_CPPFLAGS := -fPIC -Wall -Wextra -DLINUX -finline-functions -O3 -fno-strict-aliasing -fvisibility=hidden
LOCAL_LDLIBS :=-L$(SYSROOT)/usr/lib -llog
LOCAL_C_INCLUDES := /usr/include/c++/4.5/
LOCAL_CPP_EXTENSION:=.cpp
LOCAL_MODULE := udt
LOCAL_SRC_FILES := md5.cpp common.cpp window.cpp list.cpp buffer.cpp packet.cpp channel.cpp queue.cpp ccc.cpp cache.cpp core.cpp epoll.cpp api.cpp
include $(BUILD_SHARED_LIBRARY)
并把其放到src目錄下
4.分別在jni和udt4目錄下創建Android.mk,內容為
include $(all-subdir-makefiles)
APP_CPPFLAGS += -fexceptions
同時在jni目錄下創建Application.mk,內容為
APP_STL := gnustl_static
5.在jni目錄下使用ndk-build命令,我們可以發現在F:\UDT目錄下生成了libs和obj目錄,其中libs中有我們可以在Android中使用到的so庫。
下面將介紹如何在程序中使用UDT,以移植UDT例程recvfile為例。
因為UDT的庫中并沒有適用于Android的接口函數,所以我們需要再寫一個能夠在JNI中調用的庫來構建UDT庫和Android應用程序之間的橋梁。
因為本人還沒有了解新版本Android Studio中cmake的使用方法,所以我們將以傳統NDK-build方式來實現。
我們新建一個名為UDTRecv的Android Studio項目。
在app\src\main下新建jni目錄,在jni目錄下建立include和lib目錄。
把我們之前得到的so放到lib目錄中。把udt4的src目錄中所有的.h頭文件放到include目錄中。把udt4的src目錄中的recvfile.cpp拷貝到jni目錄。目錄結構如下:
編輯cpp使其支持JNI
具體如下:
添加jni頭文件引用
#include
更改主函數main()為JNI支持的函數名稱
JNIEXPORT jint JNICALL Java_net_meoi_udtrecv_MainActivity_RecvFileFromServer(
JNIEnv* env, jclass cls,jstring UDTServerAddress,jstring UDTServerPortStr,jstring RemoteFileName,jstring LocalFileName)
更改內部變量調用使其能夠正常工作。
在jni目錄下創建Android.mk,內容為
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE:= udt
LOCAL_SRC_FILES:= lib/libudt.so
LOCAL_EXPORT_C_INCLUDES:= $(LOCAL_PATH)/include
include $(PREBUILT_SHARED_LIBRARY)
include $(CLEAR_VARS)
LOCAL_CPP_EXTENSION:=.cpp
include $(CLEAR_VARS)
PATH_TO_UDT_SOURCE:=./include/
PATH_TO_LIBUDT_SO:=./lib/
LOCAL_C_INCLUDES += $(PATH_TO_UDT_SOURCE)
LOCAL_LDLIBS := -llog
LOCAL_SHARED_LIBRARIES := udt
LOCAL_MODULE := recvfile
LOCAL_SRC_FILES := recvfile.cpp
include $(BUILD_SHARED_LIBRARY)
和Application.mk,內容為
APP_STL := gnustl_static
APP_ABI := armeabi-v7a
APP_PLATFORM := android-21
在jni目錄中執行ndk-build,在上一級目錄中將生成lib目錄,我們把它更名為jniLibs,里面包含了armeabi-v7a平臺下的兩個庫文件,一個是udt核心庫,一個是recvfile例程的庫。至此我們c語言部分的代碼已經移植完畢,接下來編寫Android Java部分
編寫主程序,同時注意需要聲明JNI函數
private native static int RecvFileFromServer(String UDTServerAddress,String UDTServerPortStr,String RemoteFileName,String LocalFileName);
并且調用兩個剛剛生成的庫文件。
static {
System.loadLibrary("udt");
System.loadLibrary("udtrecvfile");
}
在工程目錄下的properties文件的末尾加上一句:
Android.useDeprecatedNdk=true
在文件gradle(Module:app)里面的buildTypes類中添加一個這樣的方法
sourceSets {
main {
jni.srcDirs = []
}
}
編譯,運行,測試
這是我第一次用github,如有問題請多多指教,謝謝
參考資料:
總結
以上是生活随笔為你收集整理的java jni udt找不到so_移植UDT到Android平台的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 实用干货:电放提单详解,与海运单、一般提
- 下一篇: Grapher中如何保存图形模板,批量处