2012-05-09 10 views
6

¿Es posible hacer la devolución de llamada de la función C/C++ en scripts de Unity, siempre que pueda crear un nuevo hilo desde los scripts? Lo intenté, pero Unity se bloquea tan pronto como se ejecutan los scripts.Interop hace que Unity se cuelgue

Busqué en Google sobre él y se encontró this thread que dice

unidad no es ni devolución de llamada multi-hilo, cualquier acceso a las clases que se extienden UnityEngine.Object sólo está permitido dentro del mismo hilo como scripts unidad se están ejecutando en, no asyncronous de otros hilos ni de las devoluciones de llamada asyncrnous de operaciones asíncronas COM/OS

Si ése es el caso para usted hay dos maneras posibles:

(1) Escriba un contenedor que obtiene estas devoluciones de llamada y las cosas y luego expone una función que permite la unidad para solicitar el siguiente evento/ objeto de datos o lo que sea en forma de bloqueo, sin hebra (2) Realice la llamada de devolución de llamada en un función estática en algo que se extiende desde System.Object y escribir el mismo tipo de lógica que el anterior para solicitar la información sobre las clases que se extienden UnityEngine.Object

Pero creo que si puedo crear un hilo y de devolución de llamada en ese hilo , todo estará bien ¿no? Estoy pensando así porque he leído hilos como this one que presenta cómo hacer que las funciones C llamen a las funciones C#. Así que pensé que si creaba un nuevo hilo, ya no sería Unity, sino que sería mono y C#.

Aquí está mi código que se estrella Unidad:

El código 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"); 
} 

El código 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(); 


    } 
} 
+1

¿Ha considerado si el bloqueo que está experimentando se debe a que no calculó la cadena en C++ antes de volver a pasarla a C# (Unity) (es decir, usando 'mono_string_new()' - consulte http: // www. mono-project.com/Embedding_Mono#Creating_objects)? – hatboyzero

Respuesta

4

La respuesta es !

He probado nuevamente el 8 de agosto de 2012 con Unity 3.5.2f2, licencia Pro. Gracias por el comentario de @ hatboyzero encontré this example.

Aunque el código en mi pregunta no funciona, el siguiente código funciona:

// C# 
using System.Runtime.InteropServices; 

class Demo { 
    delegate int MyCallback1 (int a, int b); 

    [DllImport ("MyRuntime")] 
    extern static void RegisterCallback (MyCallback1 callback1); 

    static int Add (int a, int b) { return a + b; } 
    static int Sub (int a, int b) { return a - b; } 

    void Init() 
    { 
     // This one registers the method "Add" to be invoked back by C code 
     RegisterCallback (Add); 
    } 
} 


// C 
typedef int (*callback_t) (int a, int b); 
static callback_t my_callback; 

void RegisterCallback (callback_t cb) 
{ 
    my_callback = cb; 
} 

int InvokeManagedCode (int a, int b) 
{ 
    if (my_callback == NULL){ 
     printf ("Managed code has not initialized this library yet"); 
     abort(); 
    } 
    return (*my_callback) (a, b); 
} 

no tenía para incrustar MonoRuntime como sugiere el tutorial. Solo los dos códigos anteriores resolvieron mi problema.

-5

unidad Amigo está en mal estado. Se puede bloquear en cualquier momento, solo use gnome.

+0

Not THAT Unity .... el motor de juegos Unity3D –

Cuestiones relacionadas