多语言展示
当前在线:1789今日阅读:84今日分享:32

Android Studio C++ 打包so给Unity调用

Android Studio C++ 打包so给Unity调用。在Android Studio中,进行 C++/C 封装打包成so ,然后给 Unity调用,具体如下
工具/原料
1

Android Studio

2

Unity

方法/步骤
1

打开Unity,新建一个工程,进行相关开发,具体如下图

2

进行 NDK 配置,如果没有下载,可以在 SDK Manager 中,选择对应的 NDK 以及相关的包进行下载配置,具体如下图

3

配置好 NDK 环境,然后 新建一个文件夹放置相关的 C++/C 的开发,这里为了方便,新建了一个 jni 文件夹,具体如下图

4

在文件下 添加对应的 .h 头文件,定义给Unity调用的接口,具体如下图

5

这里 Calculate.h 的具体内容为:#ifndef CALLBACKDLLIMPORT_CALCULATE_H #define CALLBACKDLLIMPORT_CALCULATE_H  //# define _DLLExport __declspec (dllexport) //标记为导出函数;  #if 0 #define EXPORT_DLL __declspec(dllexport) //导出dll声明 #else #define EXPORT_DLL #endif  #define __stdcall  //定义函数指针; typedef void (__stdcall *CPPCallback)(int tick); extern 'C' EXPORT_DLL void  SetCallback(CPPCallback callback); extern 'C' EXPORT_DLL long long dlltest();  #endif //CALLBACKDLLIMPORT_CALCULATE_H

6

然后在 .cpp 中实现 .h 定义的接口,具体如下图

7

这里 Calculate.cpp 的具体内容为:#include 'Calculate.h' long long dlltest(){     long long a = 1;     int b = 0;     while(b<1){         a=a+b;         b++;      }     return a; }  void SetCallback(CPPCallback callback){     int tick=1223;     callback(tick);

8

新建两个 mk 文件来配置打包的 .so 编译的相关信息,具体如下图

9

Android.mk 具体内容如下:LOCAL_PATH := $(call my-dir)  include $(CLEAR_VARS)  LOCAL_MODULE := Calculate LOCAL_SRC_FILES =: Calculate.cpp include $(BUILD_SHARED_LIBRARY)

10

Application.mk 具体内容如下:APP_MODULES := Calculate APP_ABI := all

11

在配置 build.gradle 相关的ndk信息,具体如下图ndk{     moduleName 'Calculate'  }  sourceSets.main {     jni.srcDir = []     jniLibs.srcDirs 'src/main/libs'  }  externalNativeBuild {     ndkBuild {         path file('src/main/jni/Android.mk')     }     /*         cmake {             path 'CMakeLists.txt'         }     */ }

12

build.gradle 的具体内容如下:apply plugin: 'com.android.application'  android {     compileSdkVersion 28     defaultConfig {         applicationId 'com.xan.callbackdllimport'         minSdkVersion 15         targetSdkVersion 28         versionCode 1         versionName '1.0'         testInstrumentationRunner 'android.support.test.runner.AndroidJUnitRunner'          ndk{             moduleName 'Calculate'          }          sourceSets.main {             jni.srcDir = []             jniLibs.srcDirs 'src/main/libs'          }          externalNativeBuild {             ndkBuild {                 path file('src/main/jni/Android.mk')             }             /*                 cmake {                     path 'CMakeLists.txt'                 }             */         }     }     buildTypes {         release {             minifyEnabled false             proguardFiles getDefaultProguardFile('proguard-android-optimize.txt'), 'proguard-rules.pro'         }     } }  dependencies {     implementation fileTree(dir: 'libs', include: ['*.jar'])     implementation 'com.android.support:appcompat-v7:28.0.0'     implementation 'com.android.support.constraint:constraint-layout:1.1.3'     testImplementation 'junit:junit:4.12'     androidTestImplementation 'com.android.support.test:runner:1.0.2'     androidTestImplementation 'com.android.support.test.espresso:espresso-core:3.0.2' }

13

准备好就可以 ndk-build 进行编译打包 so,这里可以在 Android Studio 配置一个 External Tool ,快速进行 so 编译,具体打开 File - Settings... - Tools - External Tools ,进行配置,具体如下图

14

添加一个 ndk-build,关键配置 Progam,和 Working directory。Progam 为你自己安装 ndk 的 ndk-build.cmd 的位置;Working directory 的如字义工作目录。我的配置大概如下,Progam :D:\XAN_Files\Applications\AndroidStudioSDK\Android\Sdk\ndk-bundle\ndk-build.cmd ;Working directory : $ProjectFileDir$\app\src\main,具体如下图

15

现在回到目录,右键 External Tools —— ndk-build,打包编译出libs和obj,文件夹中有对应平台的 so 文件,具体如下图

16

so 打包成功,打开 Unity,新建 Plugins文件夹,包对应的平台的so导入 Plugins 文件夹下(其实根据的目标平台需要导入即可,不必要全都导入),具体如下图

17

在工程中添加脚本,调用so下的C++/C 的接口,具体如下图

18

脚本具体内容如下:using UnityEngine;using System.Runtime.InteropServices;public class NewBehaviourScript : MonoBehaviour{    [DllImport('Calculate')] private static extern long dlltest();    [DllImport('Calculate')] private static extern void SetCallback(CSCallback callback);    public delegate void CSCallback(int tick);    static CSCallback callback;     // Use this for initialization     void Start() {        callback = CSCallbackFuction;    }    static void CSCallbackFuction(int tick)    {        Debug.Log('CSCallbackFuction ' + tick.ToString());    }     void OnGUI()    {        if (GUI.Button(new Rect(100, 100, 200, 200), 'Test DLL'))        {            long before = System.DateTime.Now.Ticks;            Debug.Log('dlltest=' + dlltest());            Debug.Log('take ' + (System.DateTime.Now.Ticks - before));        }        if (GUI.Button(new Rect(100, 300, 200, 200), 'SetCallback')) {            long before = System.DateTime.Now.Ticks;            SetCallback(callback);            Debug.Log('take ' + (System.DateTime.Now.Ticks - before));        }        if (GUI.Button(new Rect(300, 300, 200, 200), 'Test Mono')) {            long before = System.DateTime.Now.Ticks;            Debug.Log('monotest=' + monotest());            Debug.Log('take ' + (System.DateTime.Now.Ticks - before));        }    }    // Update is called once per frame     void Update () {  }     long monotest() {        long a = 1;        int b = 0;        while (b<1)  {            a =a+b;            b++;        }        return a;    }}

19

脚本编译正确,回到Unity场景,把脚本添加到场景中,具体如下图

20

编译的时候可能会出现 same name 包名的问题,具体如下图

21

选中 各个平台的 so,把CPU 做对应的修改即可,具体如下图

22

然后配置 Android 环境,打包编译到机器上,运行效果如下

23

分别点击三个按钮,即可触发对应的 so 调用和打印,具体打印效果如下

注意事项

您的支持,是我们不断坚持知识分享的动力,若帮到您,还请帮忙投票有得;若有疑问,请留言

推荐信息