2012-05-09 9 views
6

スクリプトから新しいスレッドを作成できるのであれば、UnityスクリプトにC/C++関数のコールバックを行うことは可能ですか?私は試しましたが、スクリプトが実行されるとただちにUnityがクラッシュします。 InteropによってUnityがクラッシュする

が、私はそれについてGoogleで検索して

Unityがコールバックされていないというthis threadもスレッドセーフを見つけ、UnityEngine.Objectを拡張 クラスへのアクセスは、ユニティ・スクリプトと同じスレッド 内から許可されて実行されています

他のスレッドからもasyncrnousコールバックからCOM/OS非同期操作からasyncronousない、中にあなたのためのケースthatsの2つの方法がある場合:

は、

(1)これらのコールバックを取得し、それらをキューに入れるラッパーを作成し、 がユニティが次のイベントを要求する機能を公開する/ データオブジェクトまたはブロックされていないスレッド化されていないフォーム内の何か( コールバックを のSystem.Objectから延びる何かの静的関数とUnityEngine.Object

を拡張するクラスの 情報を要求するために、上記の論理と同じ種類を書くしかし、私はスレッドを作成した場合を考えると、そのスレッドにコールバックそれは大丈夫でしょうか?私はthis oneのようなスレッドを読んでいるので、このように考えています。これは、C関数を呼び出してC#関数を呼び出す方法を紹介しています。だから、もし私が新しいスレッドを作ると、それはもはやユニティではなく、単なるモノとC#になると私は推論しました。ここで

はUnityのクラッシュ私のコードです:

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

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

あなたが経験しているクラッシュがC++で文字列をマーシャリングしないためであるかどうかを検討しましたか?C#(Unity)に戻す前に(つまり 'mono_string_new()'を使用してください - http:// www。 mono-project.com/Embedding_Mono#Creating_objects)? – hatboyzero

答えて

4

回答ははいです!

私はUnity 3.5.2f2、Proライセンスで2012年8月8日に再度テストしました。 @ hatboyzeroさんのコメントthis exampleをありがとうございました。

私の質問のコードは動作しませんが、次のコードは動作します:

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

私はチュートリアルが示唆するようMonoRuntimeを埋め込む必要はありませんでした。ちょうど上記の2つのコードは私の問題を解決しました。

-5

デュード団結を台無しにされています。いつでもクラッシュすることがあります。ただgnomeを使用してください。

+0

それ以外のUnity ... Unity3Dゲームエンジン –

関連する問題