プラグインでc++と連携する(Android)

この記事は2017年07月06日にqiitaに投稿した内容です。

環境

Unity5.6.2f1

概要

C#側からc++側に関数を登録して、c++側から登録した関数を呼び出します エコープログラムです

AndroidStudioとUnityの事前設定

以下を参照してプロジェクトを作成する Android用ネイティブレンダリングPlugin(c++[so])の作成 「libnativecpp.so」としてエクスポートされるようにする 「MultiThreadedRendering」にチェックを入れなくていい  今回はレンダリングは関係ない為

CMakeLists.txt

# For more information about using CMake with Android Studio, read the
# documentation: https://d.android.com/studio/projects/add-native-code.html
# Sets the minimum version of CMake required to build the native library.
cmake_minimum_required(VERSION 3.4.1)

# Creates and names a library, sets it as either STATIC
# or SHARED, and provides the relative paths to its source code.
# You can define multiple libraries, and CMake builds them for you.
# Gradle automatically packages shared libraries with your APK.
add_library( # Sets the name of the library.
             native-lib

             # Sets the library as a shared library.
             SHARED

             # Provides a relative path to your source file(s).
             Test.cpp
)

# Specifies a path to native header files.
include_directories( Unity/ )

# Searches for a specified prebuilt library and stores the path as a
# variable. Because CMake includes system libraries in the search path by
# default, you only need to specify the name of the public NDK library
# you want to add. CMake verifies that the library exists before
# completing its build.
find_library( # Sets the name of the path variable.
              log-lib

              # Specifies the name of the NDK library that
              # you want CMake to locate.
              log
)

# Specifies libraries CMake should link to your target library. You
# can link multiple libraries, such as libraries you define in this
# build script, prebuilt third-party libraries, or system libraries.
target_link_libraries( # Specifies the target library.
                       native-lib
                       # Links the target library to the log library
                       # included in the NDK.
                       ${log-lib}
)

プログラム

Assets/TestNativePlugin.cs

using UnityEngine;
using UnityEngine.Events;
using UnityEngine.UI;
using System.Runtime.InteropServices;

public class TestNativePlugin : MonoBehaviour 
{
    [SerializeField] Text _text = null;

    [DllImport ("nativecpp")]
    public static extern void SetEchoCallbackFunction( UnityAction<string> func );
    [DllImport ("nativecpp")]
    public static extern void TestEcho( string message );

    private static TestNativePlugin _instance = null;
    private void Awake()
    {
        _instance = this;
    }

    private void OnDestroy()
    {
        _instance = null;
    }

    private void OnApplicationQuit()
    {
        OnDestroy();
    }

    private void OnEnable()
    {
        SetEchoCallbackFunction( OnNativeCallback );
    }

    private void OnDisable()
    {
        SetEchoCallbackFunction( null );
    }

    private void Start() 
    {
        TestEcho( "hello world!" );
    }

    private void OnNativeCallback( string message )
    {
        Debug.Log( message );
        _instance.SetText( message );
    }

    private void SetText( string message )
    {
        if( _text == null )
            return;
        _text.text = message;
    }
}

Test.cpp

#include "IUnityInterface.h"
#include <math.h>
#include <stdio.h>
#include <assert.h>

extern "C"
{
    using EchoCallback = void(*)( const char* );
    namespace
    {
        EchoCallback onEchoCallback = NULL;
    }

    UNITY_INTERFACE_EXPORT void SetEchoCallbackFunction( EchoCallback func )
    {
        onEchoCallback = func;
    }

    UNITY_INTERFACE_EXPORT void TestEcho( const char* pMessage )
    {
        if ( onEchoCallback == NULL )
            return;
        onEchoCallback( pMessage );
    }
}