czy można w ogóle wywołać wywołanie funkcji C/C++ w skryptach Unity, pod warunkiem, że można utworzyć nowy wątek ze skryptów? Próbowałem, ale Unity ulega awarii, gdy tylko skrypty zostaną wykonane.Interop powoduje awarię Unity
google o nim i znaleźć this thread który mówi
Unity nie jest ani callback threadsafe dowolny dostęp do klas, które przedłużyć UnityEngine.Object jest dozwolona tylko w obrębie tego samego wątku jedności jako skrypty są uruchomione w nie Asyncronous z innych wątków ani z asyncrnous wywołania zwrotne z operacji asynchronicznych COM/OS
Jeśli ów w Twoim przypadku możliwe są dwa sposoby:
(1) Napisz wrapper, który pobiera te wywołania zwrotne i kolejkuje rzeczy oraz , a następnie eksponuje funkcję, która pozwala jedności zażądać następnego zdarzenia/ obiektu danych lub cokolwiek w postaci blokującej, niegwintowanej (2) Spraw, aby wywołanie zwrotne stało się funkcja statyczna na coś wystającego z System.Object i pisać tego samego rodzaju logiki jak wyżej do żądania informacje o zajęciach rozciągających UnityEngine.Object
Ale myślę, że jeśli i utworzyć wątku i oddzwanianie do tego wątku , będzie dobrze, prawda? Myślę tak, ponieważ czytałem wątki takie jak this one, który wprowadza, jak wywoływać funkcje C wywołujące funkcje C#. Tak więc rozumowałem, że jeśli utworzę nowy wątek, to już nie będzie Unity, będzie to po prostu mono i C#.
Tu jest mój kod, który rozbija jedność:
C++ Kod:
#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# Kod:
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();
}
}
Czy zastanawiałeś się, czy twoja awaria, której doświadczasz, nie powoduje marshowania ciągu w C++ przed przekazaniem go z powrotem do C# (Unity) (tj. Używając 'mono_string_new()' - patrz http: // www. mono-project.com/Embedding_Mono#Creating_objects)? – hatboyzero