2012-05-09 14 views
6

Denedim ama komutlar çalıştırılır yüklenmez Unity çöküyor. Tümleşik nedenler Komut dizisinden yeni bir iş parçacığı oluşturabilmeniz için Unity komut dosyalarına C/C++ işlevinin geri çağrılmasını Unity komut dosyalarına dönüştürmek mümkün

bu konuda googled ve

Birlik callback değildir diyor this thread ne de threadsafe bulundu UnityEngine.Object uzatmak sınıflara herhangi erişimi sadece birlik komut ile aynı parçacığı içinde izin verilmektedir çalıştıran diğer iplikler gelen ne de COM/OS zaman uyumsuz operasyonlarından asyncrnous geri aramaları gelen asenkron değil, içinde

sizin için durum şu varsa iki olası yolları:

(1) Bu geri çağrıları alan ve numaralı kuyruğu alıp bir sonraki olayı/ veri nesnesini veya herhangi bir engelleme, işlenmemiş formda (2) geri arama çağrısı yapmasını sağlayan bir işlev ortaya koyan bir sarmalayıcı yaz System.Object'ten uzanan şey statik fonksiyonu ve UnityEngine.Object

uzanan sınıflara bilgi istemek için yukarıdaki mantığı aynı tür yazmak Ama bir iş parçacığı oluşturursanız düşünmek ve bu iplik haline geri arama iyi olacak mı? Bunun gibi düşünüyorum çünkü C# işlevlerini geri çağırırken C işlevlerinin nasıl yapılacağını tanıtan this one gibi konuları okudum. Bu yüzden, eğer yeni bir iş parçacığı yaratırsam, artık birlik değil, sadece mono ve C# olacak.

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# kodu:

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

Yaşadığınız kilitlenmenin C++ dizgesini C# (Unity) 'ye (örneğin' mono_string_new() ') iletmeden önce dizgiyi dizilememesinden mi, yoksa http: // www. mono-project.com/Embedding_Mono#Creating_objects)? – hatboyzero

cevap

4

Cevap Evet!

Unity 3.5.2f2, Pro lisansıyla 8 Ağustos 2012 tarihinde tekrar test oldum. @ Hatboyzero'nun yorumu için teşekkürler this example'u buldum. Benim söz konusu kod çalışmaz rağmen

, aşağıdaki kod çalışır:

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

Ben öğretici anlaşılacağı gibi MonoRuntime gömmek zorunda değildi. Sadece yukarıdaki iki kod parçası benim problemimi çözdü.

-5

Dostum birlik pislik

İşte Unity çöküyor benim kodudur. Her zaman çökebilir, sadece gnome kullanın.

+0

Unity3 Unity3D Oyun motoru –