是否可以将C / C ++函数回调到Unity脚本中,前提是你可以从脚本创建一个新线程?我试过但是一旦脚本执行完毕Unity就会崩溃
我用Google搜索并发现this thread表示
Unity不是回调也不是线程安全,任何对类的访问权限 只允许在同一个线程内扩展UnityEngine.Object 因为统一脚本正在运行,而不是来自其他线程的异步 也不是来自COM / OS异步操作的异步回调
如果是这种情况,有两种可能的方法:
(1)编写一个包装器来获取这些回调并对这些东西进行排队 然后公开一个允许统一请求下一个事件的函数/ 数据对象或其他任何阻塞,无螺纹的形式(2)制作 callbacks调用一个静态函数来扩展 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();
}
}
答案 0 :(得分:4)
答案是是!
我在2012年8月8日再次使用Unity 3.5.2f2,Pro许可证进行了测试。感谢@ 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。上面两段代码解决了我的问题。
答案 1 :(得分:-5)
老兄的团结搞砸了。它可以随时崩溃,只需使用gnome。