【发布时间】:2012-05-09 21:30:05
【问题描述】:
是否有可能将 C/C++ 函数回调到 Unity 脚本中,前提是您可以从脚本创建一个新线程?我试过了,但是一旦脚本执行,Unity 就会崩溃.
我在 Google 上搜索了一下,发现 this thread 上面写着
Unity 不是回调也不是线程安全的,任何对类的访问 仅允许在同一线程内扩展 UnityEngine.Object 由于统一脚本正在运行,而不是与其他线程异步 也不是来自 COM / OS 异步操作的异步回调
如果你是这种情况,有两种可能的方法:
(1) 编写一个包装器来获取这些回调并将这些内容排队并 然后暴露一个允许unity请求下一个事件的函数/ 数据对象或任何阻塞、非线程形式的东西 (2) 使 回调调用从扩展的东西上的静态函数 System.Object 并编写与上述相同的逻辑来请求 有关扩展 UnityEngine.Object 的类的信息
但我认为如果我创建一个线程并回调到该线程中,就可以了,对吧?我这样想是因为我读过像 this one 这样的线程,它介绍了如何制作C 函数回调 C# 函数。所以我推断如果我创建一个新线程,它就不再是 Unity,它只是单声道和 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();
}
}
【问题讨论】:
-
您是否考虑过您遇到的崩溃是否是由于在将字符串传递回 C# (Unity) 之前未在 C++ 中编组字符串(即使用 'mono_string_new()' - 请参阅 @ 987654323@)?
标签: c# c callback interop unity3d