2012-05-09 13 views
6

ist es überhaupt möglich, C/C++ - Funktionsrückrufe in Unity-Skripte zu machen, vorausgesetzt, Sie können einen neuen Thread aus den Skripten erstellen? Ich habe versucht, aber Unity stürzt ab, sobald die Skripte ausgeführt werden.Interop verursacht Unity zum Absturz

ich es gegoogelt und fand this thread die nicht

Unity sagt wird Rückruf noch THREAD, jeder Zugriff auf Klassen, die UnityEngine.Object erweitern ist nur aus dem gleichen Thread als Einheit Skripten erlaubt laufen in, nicht asynchroner von anderen Threads noch von asyncrnous Rückrufen von COM/O asynchronen Operationen

Wenn das ist der Fall für Sie gibt es zwei Möglichkeiten:

(1) Schreibe einen Wrapper, der diese Callbacks bekommt und die stuffs einreiht und dann eine Funktion exponiert, die es unity ermöglicht, das nächste event/ Datenobjekt oder was auch immer in einem blockierenden, nicht gewindelosen Formular anzufordern (2) Mache die Callbacks in ein statische Funktion auf etwas von System.Object erstreckt und wie oben die gleiche Art von Logik schreiben die Informationen über Klassen zu beantragen UnityEngine.Object erstreckt

Aber ich denke, wenn ich einen Thread und Rückruf in diesem Thread erstellen Es wird alles gut, oder? Ich denke so, weil ich Threads wie this one gelesen habe, die vorstellt, wie C-Funktionen aufgerufen werden, die C# -Funktionen aufrufen. Also dachte ich mir, wenn ich einen neuen Thread erstelle, ist es nicht mehr Unity, sondern nur Mono und C#.

Hier ist mein Code, der Unity stürzt:

Der C++ Code:

#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"); 
} 

Der C# -Code:

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

Haben Sie darüber nachgedacht, ob der Absturz, der auftritt, darauf zurückzuführen ist, dass die Zeichenfolge in C++ nicht vorsortiert wird, bevor sie an C# (Unity) übergeben wird (z. B. mit 'mono_string_new()' - siehe http: // www. monoproject.com/Embedding_Mono#Creating_objects)? – hatboyzero

Antwort

4

Die Antwort ist Ja!

Ich habe erneut am 8. August 2012 mit Unity 3.5.2f2, Pro-Lizenz getestet. Danke für @ hutboyzeros Kommentar Ich fand this example.

Obwohl der Code in meine Frage nicht funktioniert, der folgende Code funktioniert:

// 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); 
} 

ich nicht MonoRuntime einzubetten hatte wie das Tutorial vermuten lässt. Nur die obigen zwei Teile des Codes lösten mein Problem.

-5

Geck Einheit ist durcheinander. Es kann jederzeit abstürzen, benutze einfach Gnome.

+0

Nicht diese Einheit .... die Unity3D Game Engine –

Verwandte Themen