java jni udt找不到so_移植UDT到Android平台

本文详细介绍了如何将UDT(UDP Based Data Transfer)协议移植到Android平台,包括创建jni目录、配置Android.mk文件、构建NDK项目、处理JNI接口以及编写Android Java部分。通过移植和编译,最终在Android应用中成功使用UDT进行数据传输。
摘要由CSDN通过智能技术生成

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目录。目录结构如下:

list-102x300.png

编辑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,如有问题请多多指教,谢谢

参考资料:

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值