1. DLL の方法:
C++ コード: DLL にコンパイル、Unity にインポート
#pragma once
#include <map>
#include <string>
//导出宏定义
#define _DllExport _declspec(dllexport)
//函数指针
typedef void (*NativeCallback)(const char*);
extern "C"
{
//注意这里字符串不能用C++的std::string,和C#的string不等价,等价的是char*,即字符数组
_DllExport void RegisterNativeCallback(const char* functionName, NativeCallback callback);
_DllExport void UpdateNative();
}
//缓存C#函数的地址
std::map<std::string, NativeCallback> _callbackMap;
//导出让C#调用,注册C#端的函数,注册后就可以在C++端调用C#的函数,本质就职把C#函数的地址给到C++,C++调用。
_DllExport void RegisterNativeCallback(const char* functionName, NativeCallback callback)
{
_callbackMap[std::string(functionName)] = callback;
}
//导出让C#调用
_DllExport void UpdateNative()
{
//调用C#端的函数,可以在Unity性能分析界面看到Native update,用此方法可以在Unity界面查看C++代码的耗时
_callbackMap[std::string("BeginSample")]("Native update");
_callbackMap[std::string("Log")]("Native Log");
_callbackMap[std::string("EndSample")]("Native update");
}
C# コード:
using AOT;
using System;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Profiling;
namespace Haha
{
public class TestCPPLib : MonoBehaviour
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate void NativeCallback(string args);
[DllImport("CPPLib")]
static extern void RegisterNativeCallback(string functionName, IntPtr callback);
[DllImport("CPPLib")]
static extern void UpdateNative();
[MonoPInvokeCallback(typeof(NativeCallback))]
static void CallbackLog(string args)
{
Debug.Log(args);
}
[MonoPInvokeCallback(typeof(NativeCallback))]
static void CallbackBeginSample(string args)
{
Profiler.BeginSample(args);
}
[MonoPInvokeCallback(typeof(NativeCallback))]
static void CallbackEndSample(string args)
{
Profiler.EndSample();
}
void Start()
{
//调用C++函数,注册C#函数
RegisterNativeCallback("Log", Marshal.GetFunctionPointerForDelegate(new NativeCallback(CallbackLog)));
RegisterNativeCallback("BeginSample", Marshal.GetFunctionPointerForDelegate(new NativeCallback(CallbackBeginSample)));
RegisterNativeCallback("EndSample", Marshal.GetFunctionPointerForDelegate(new NativeCallback(CallbackEndSample)));
}
private void Update()
{
//调用C++函数
UpdateNative();
}
}
}
2. プラグインとして il2cpp のみをサポートする C++ ソース コードもあります。
C++ コード: Unity の Assets ディレクトリに直接配置します。
C# ソース ファイル: 違いは、インポート時に特定のファイル名を記述せず、単に __Internal と記述することです。これは、IL2CPP バックエンド メソッドを使用すると、C++ ソース ファイルがプロジェクト内に配置され、一緒にコンパイルされるためです。
using AOT;
using System;
using System.Runtime.InteropServices;
using UnityEngine;
using UnityEngine.Profiling;
namespace Haha
{
public class TestCPPLib : MonoBehaviour
{
[UnmanagedFunctionPointer(CallingConvention.Cdecl)]
delegate void NativeCallback(string args);
//区别在这里:
[DllImport("__Internal")]
static extern void RegisterNativeCallback(string functionName, IntPtr callback);
[DllImport("__Internal")]
static extern void UpdateNative();
[MonoPInvokeCallback(typeof(NativeCallback))]
static void CallbackLog(string args)
{
Debug.Log(args);
}
[MonoPInvokeCallback(typeof(NativeCallback))]
static void CallbackBeginSample(string args)
{
Profiler.BeginSample(args);
}
[MonoPInvokeCallback(typeof(NativeCallback))]
static void CallbackEndSample(string args)
{
Profiler.EndSample();
}
void Start()
{
RegisterNativeCallback("Log", Marshal.GetFunctionPointerForDelegate(new NativeCallback(CallbackLog)));
RegisterNativeCallback("BeginSample", Marshal.GetFunctionPointerForDelegate(new NativeCallback(CallbackBeginSample)));
RegisterNativeCallback("EndSample", Marshal.GetFunctionPointerForDelegate(new NativeCallback(CallbackEndSample)));
}
private void Update()
{
UpdateNative();
}
}
}
手間のかかるC++のコードだけ見ると、unityはC++のインターフェースを提供している方が便利で、最後に動画で紹介しています。
Unity公式マニュアル
//使用这两个原生接口,需要在C++项目属性配置:VC++目录->包含目录 或 C/C++->常规->附加包含目录,添加Unity这两个文件的文件路径
#include <IUnityInterface.h>
#include <IUnityProfiler.h>
static IUnityProfiler* s_UnityProfiler = NULL;
static const UnityProfilerMarkerDesc* s_MyPluginMarker = NULL;
static bool s_IsDevelopmentBuild = false;
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginLoad(IUnityInterfaces * unityInterfaces)
{
s_UnityProfiler = unityInterfaces->Get<IUnityProfiler>();
if (s_UnityProfiler == NULL)
return;
s_IsDevelopmentBuild = s_UnityProfiler->IsAvailable() != 0;
s_UnityProfiler->CreateMarker(&s_MyPluginMarker, "MyCustomMethod", kUnityProfilerCategoryOther, kUnityProfilerMarkerFlagDefault, 0);
}
extern "C" void UNITY_INTERFACE_EXPORT UNITY_INTERFACE_API UnityPluginUnload()
{
s_UnityProfiler = NULL;
}
extern "C" void UNITY_INTERFACE_EXPORT InterfaceUpdate()
{
if (s_IsDevelopmentBuild)
{
s_UnityProfiler->BeginSample(s_MyPluginMarker);
}
//测试耗时代码
for (int i = 0; i < 100000; i++)
{
}
if (s_IsDevelopmentBuild)
{
s_UnityProfiler->EndSample(s_MyPluginMarker);
}
}
IL2CPP パッケージングのテストについて:
1. Unity を介して直接ビルドします。構造は次のとおりです: サイズ 313M
2. VS ソリューションを作成することにより (VS にブレークポイントを設定し、C++ コードを変更およびデバッグできます)、VS でビルドします。 、およびインターフェイスの設定でビルドします。
構造は次のとおりです。bin ディレクトリにはソフトウェアのデータ ディレクトリが含まれ、特定の生成された exe はそれぞれのプラットフォームの下にあります。
最後に、次のように、bin ディレクトリのデータ フォルダを対応するプラットフォームの exe と一緒に配置します:
162M のサイズを超える lib、pdb、および exp は削除でき、テストは動作に影響しません。 : 50.8M のサイズ
結論: 対より小さいボリュームで構築されました。