возможно ли вообще сделать обратный вызов функции C/C++ в сценарии Unity, при условии, что вы можете создать новый поток из сценариев? Я пытался, но Unity падает, как только сценарии выполняются .
Я погуглил об этом и нашел эту ветку, в которой говорится
Unity не является обратным вызовом или потокобезопасным, любой доступ к классам, которые расширение UnityEngine.Object разрешено только из того же потока поскольку выполняются сценарии единства, а не асинхронно с другими потоками ни от асинхронных обратных вызовов из асинхронных операций COM/OS.
Если это так, есть два возможных пути:
(1) Напишите оболочку, которая получает эти обратные вызовы и ставит их в очередь и затем выставьте функцию, которая позволяет единству запрашивать следующее событие/ объект данных или что-то еще в блокирующей форме без резьбы (2) Сделайте обратные вызовы вызывают статическую функцию на чем-то, простирающемся от System.Object и напишите ту же логику, что и выше, чтобы запросить информация о классах, расширяющих UnityEngine.Object
Но я думаю, что если я создам поток и обратная связь в этот поток, все будет в порядке, верно? Я так думаю, потому что я читал такие темы, как этот , в котором рассказывается, как заставить функции C вызывать функции C#.Поэтому я решил, что если я создам новый поток, это будет уже не Unity, а просто моно и C#.
Вот мой код, вызывающий сбой Unity:
Код C++:
#include
// #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();
}
}