C言語側
これは無印c言語で書いていますが、C関数が出せればなんでもOK C++やRust等
int test(int x,int y);
int test(int x,int y)
{
return x+y;
}
dylibをビルド
gcc -dynamiclib -o test.dylib test.c
test.dylibが出来るのでStreamingAssetsに置きます。
Unity側(C#)
using System;
using System.IO;
using System.Runtime.InteropServices;
using UnityEngine;
public class DllTest : MonoBehaviour
{
[DllImport("__Internal")]
private static extern IntPtr dlopen(string filename, int flag);
[DllImport("__Internal")]
private static extern int dlclose(IntPtr handle);
[DllImport("__Internal")]
private static extern IntPtr dlsym(IntPtr handle, string name);
delegate int testDelegate(int x, int y);
// Start is called before the first frame update
void Start()
{
var dll = dlopen(Path.Combine(Application.streamingAssetsPath, "test.dylib"), 1);
var testPtr = dlsym(dll,"test");
var testDelegate = Marshal.GetDelegateForFunctionPointer<testDelegate>(testPtr);
var result = testDelegate( 200, 300);
Debug.Log($"result = {result}");
dlclose(dll);
}
}
dlopenの第二引数「1」はRTLD_LAZYです(dlfcn.hで定義、Cコードで出力して確認しました)
結果
何か適当なオブジェクトにアタッチして実行してください。コンソールに次の出力が出ればOK
result = 500
解説
WindowsだとDLLをLoadLibrary、GetProcAddress、FreeLibraryとかで処理する奴ですね。macOSの記事がぱっと見つからなかったのでメモ。
Unixのダイナミックリンクライブラリを扱う標準関数なんで、Linuxとかでも似たことは出来るかも?(試していない)