スクリプトから新しいスレッドを作成できる場合、C / C ++関数をUnityスクリプトにコールバックすることは可能ですか?試しましたが、スクリプトが実行されるとすぐにUnityがクラッシュします。
私はそれについてグーグルで検索し、このスレッドを見つけました。
Unityはコールバックでもスレッドセーフでもありません。UnityEngine.Objectを拡張するクラスへのアクセスは、Unityスクリプトが実行されているのと同じスレッド内からのみ許可され、他のスレッドからの非同期やCOM/OS非同期操作からの非同期コールバックからは許可されません。
その場合、2つの方法が考えられます。
(1)これらのコールバックを取得してキューに入れるラッパーを作成し、Unityが次のイベント/データオブジェクトなどをブロックするスレッド化されていない形式で要求できるようにする関数を公開します(2)コールバックを何かの静的関数に呼び出しますSystem.Objectから拡張し、上記と同じ種類のロジックを記述して、UnityEngine.Objectを拡張するクラスに関する情報を要求します。
しかし、スレッドを作成してそのスレッドにコールバックすれば、大丈夫だと思いますよね?C#関数を呼び出すC関数を作成する方法を紹介するこのようなスレッドを読んだので、私はこのように考えています。そのため、新しいスレッドを作成すると、Unityではなくなり、モノラルとC#になると考えました。
Unityをクラッシュさせる私のコードは次のとおりです。
C ++コード:
#include <iostream>
// #include "stdafx.h"
typedef int (__stdcall * Callback)(const char* text);
Callback Handler = 0;
extern "C" __declspec(dllexport)
void __stdcall SetCallback(Callback handler) {
Handler = handler;
}
extern "C" __declspec(dllexport)
void __stdcall TestCallback() {
int retval = Handler("hello world");
}
C#コード:
using UnityEngine;
using System;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using System.Threading;
class UnManagedInterop : MonoBehaviour {
private delegate int Callback(string text);
private Callback mInstance; // Ensure it doesn't get garbage collected
public void Test() {
mInstance = new Callback(Handler);
SetCallback(mInstance);
TestCallback();
}
private int Handler(string text) {
// Do something...
print(text);
return 42;
}
[DllImport("test0")]
private static extern void SetCallback(Callback fn);
[DllImport("test0")]
private static extern void TestCallback();
void Start()
{
Thread oThread = new Thread(new ThreadStart(Test));
// Start the thread
oThread.Start();
}
}