• android studio编译SDL so库


    一、下载源码

    SDL官网
    在这里插入图片描述
    在这里插入图片描述

    二、解压,拷贝android项目,并重新命名

    2.1、解压

    在这里插入图片描述

    2.2,重命名项目名称(androidSDL)AndroidSDL Github

    在这里插入图片描述

    三、导入头文件和源文件,修改android.mk文件

    3.1、在jni目录下创建SDL2文件夹,并拷贝相关头文件和源文件到该目录下

    在这里插入图片描述

    3.2、在jni/src目录下创建.cpp文件

    在这里插入图片描述
    main.cpp

    #include "SDL.h"
    int main(int,char**){
       return 0;
    }
    
    • 1
    • 2
    • 3
    • 4

    3.3、修改jni/src下的android.mk文件

    在这里插入图片描述
    Android.mk

    LOCAL_PATH := $(call my-dir)
    
    include $(CLEAR_VARS)
    
    LOCAL_MODULE := main
    
    SDL_PATH := ../SDL2
    
    LOCAL_C_INCLUDES := $(LOCAL_PATH)/$(SDL_PATH)/include
    
    # Add your application source files here...
    LOCAL_SRC_FILES := main.cpp
    
    LOCAL_SHARED_LIBRARIES := SDL2
    
    LOCAL_LDLIBS := -lGLESv1_CM -lGLESv2 -lOpenSLES -llog -landroid
    
    include $(BUILD_SHARED_LIBRARY)
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18

    四、使用NDK编译

    4.1、环境变量path配置ndk路径

    在这里插入图片描述

    4.2、打开cmd命令窗口,进入到androidSDL/app/jni/目录,然后执行"ndk-build"命令进行编译

    在这里插入图片描述

    4.3、根目录下生成libs目录,里面会有对应的so库

    在这里插入图片描述
    在这里插入图片描述

    五、依赖so库

    5.1、创建新项目(AndroidSDLThread)Github

    在这里插入图片描述

    5.2、src/main创建jniLibs目录,拷贝so库

    在这里插入图片描述

    5.3、src/main/cpp下创建include文件夹,拷贝SDL头文件至此

    在这里插入图片描述

    5.4、CMakeList.txt文件下配置SDL头文件和库文件

    cmake_minimum_required(VERSION 3.18.1)
    project("androidsdlthread")
    
    #SDL统一路径
    set(sdl_path ${CMAKE_SOURCE_DIR}/../jniLibs/${ANDROID_ABI})
    #添加SDL头文件
    include_directories(${CMAKE_SOURCE_DIR}/include/SDL)
    #添加SDL库
    add_library(sdl SHARED IMPORTED)
    set_target_properties(sdl PROPERTIES IMPORTED_LOCATION ${sdl_path}/libSDL2.so)
    
    add_library(sdl_shared SHARED IMPORTED)
    set_target_properties(sdl_shared PROPERTIES IMPORTED_LOCATION ${sdl_path}/libc++_shared.so)
    
    add_library(sdl_main SHARED IMPORTED)
    set_target_properties(sdl_main PROPERTIES IMPORTED_LOCATION ${sdl_path}/libmain.so)
    
    add_library(
            androidsdlthread
            SHARED
            native-lib.cpp
            ${CMAKE_SOURCE_DIR}/logger.h)
    find_library(
            log-lib
            log)
    target_link_libraries( # Specifies the target library.
            androidsdlthread
            sdl
            sdl_shared
            sdl_main
            -landroid
            ${log-lib})
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32

    在这里插入图片描述

    六、使用SDL信号量,实现等待通知机制

    SDL(Simple DirectMedia Layer)库提供了信号量(semaphore)的支持,用于实现线程间的同步和通信。信号量是一种计数器,用于控制对共享资源的访问,可以实现多线程之间的同步和互斥,确保线程安全和资源的正确访问。

    • 创建信号量:调用SDL_CreateSemaphore() 函数创建一个信号量对象。在底层,SDL库会调用操作系统提供的原生信号量创建函数,如sem_init()(Linux)或CreateSemaphore()(Windows)。
    • 等待信号量:调用SDL_SemWait() 或类似的函数等待信号量。在底层,SDL库会调用操作系统提供的原生信号量等待函数,如sem_wait()(Linux)或WaitForSingleObject()(Windows)。如果信号量的计数值大于0,则将计数值减1,线程可以继续执行。如果计数值为0,则线程会被阻塞,直到有其他线程调用SDL_SemPost()增加了信号量的计数值。
    • 发送通知:调用SDL_SemPost() 函数增加信号量的计数值。在底层,SDL库会调用操作系统提供的原生信号量增加函数,如sem_post()(Linux)或ReleaseSemaphore()(Windows)。增加计数值后,如果有线程正在等待该信号量其中一个线程将被唤醒,可以继续执行。
    • 销毁信号量:调用SDL_DestroySemaphore() 函数销毁信号量对象。在底层,SDL库会调用操作系统提供的原生信号量销毁函数,如sem_destroy()(Linux)或CloseHandle()(Windows)。

    6.1、声明native方法

        public native void startSDLThread();
    
        public native void postSDL();
    
        public native void releaseSDL();
    
    • 1
    • 2
    • 3
    • 4
    • 5

    6.2、生成jni函数

    #include 
    #include 
    
    extern "C" {
    #include 
    #include "logger.h"
    
    SDL_sem *g_sem = NULL;
    int g_task_exit = 0;
    int task1(void *data);
    int task2(void *data);
    int number=0;
    
    JNIEXPORT void JNICALL
    Java_com_anniljing_androidsdlthread_MainActivity_startSDLThread(JNIEnv *env, jobject thiz) {
        g_task_exit=0;
        g_sem = SDL_CreateSemaphore(0);
        SDL_CreateThread(task1, "task1", NULL);
        SDL_CreateThread(task2, "task2", NULL);
    }
    JNIEXPORT void JNICALL
    Java_com_anniljing_androidsdlthread_MainActivity_postSDL(JNIEnv *env, jobject thiz) {
        if (g_sem) {
            SDL_SemPost(g_sem);
        }
    }
    
    JNIEXPORT void JNICALL
    Java_com_anniljing_androidsdlthread_MainActivity_releaseSDL(JNIEnv *env, jobject thiz) {
        g_task_exit = 1;
        SDL_DestroySemaphore(g_sem);
        g_sem = NULL;
    }
    int task1(void *data) {
        while (!g_task_exit) {
            if (g_sem) {
                LOGD("task1 SemWait");
                SDL_SemWait(g_sem);
                number++;
                LOGD("task1 number:%d\n",number);
            }
        }
        return 0;
    }
    int task2(void *data) {
        while (!g_task_exit) {
            if (g_sem) {
                LOGD("task2 SemWait");
                SDL_SemWait(g_sem);
                number++;
                LOGD("task2 number:%d\n",number);
            }
        }
        return 0;
    }
    }
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54
    • 55
    • 56
    • 57
    • 58

    6.3、编译运行

    在这里插入图片描述
    在这里插入图片描述
    我们需要把这个文件夹拷贝到自己的项目
    在这里插入图片描述
    在这里插入图片描述

    • 启动了两个线程
    • 虽然线程2被唤起的次数多一些,但是当线程1执行的时候,变量number也是同步的
  • 相关阅读:
    服务器百万并发的原理与实现
    PyQt5快速开发与实战 4.3 QLabel and 4.4 文本框类控件
    还不轻松heic怎么转换?无需担心,使用这几款heic转换器轻松实现
    【二】2D测量 Metrology——read_metrology_model()算子
    2024考研计算机考研复试-每日重点(第二十期)
    如何让你的程序支持lua脚本
    使用HTML CSS制作静态网站【中秋节】
    【广州华锐互动】VR全景工厂虚拟导览,虚拟现实技术提升企业数字化信息管理水平
    mysql为什么会选错索引,以及优化器是如何选择索引的
    机器学习 笔记05——特征工程之特征处理:字典特征提取、文本特征提取
  • 原文地址:https://blog.csdn.net/u011557841/article/details/134425413