我的C++ Unity 插件在编辑器中运行一次,但不能运行两次

My C++ Unity plugin runs once in the editor but not twice

本文关键字:运行 一次 但不能 两次 C++ Unity 编辑器 插件 我的      更新时间:2023-10-16

我有一个调用C++代码的插件。当游戏启动时,它会调用以下extern C++函数:

void startPlugin() {
  MyClass::instance = new MyClass();
  MyClass::instance->process();
}

process 方法运行一个无限循环,该循环处理数据并继续,只要keepRunning成员为真。因为它运行无限循环并阻塞,所以在它自己的线程中调用此方法。

当游戏结束时,我从 C# 运行这个extern方法:

void stopPlugin() {
  MyClass::instance->keepRunning = false;
  sleep(1); // Make sure the process loop is done. It should take less than one frame, but just to be sure...
  MyClass::cleanup();
}

它指的是这种方法:

void MyClass::cleanup() {
  delete instance;
  instance = NULL;
}

根据控制台所说的,这些方法确实正在运行。

在Mac上,这是第一次工作。我可以在编辑器中启动游戏并在编辑器中停止它,一切正常。但是,如果我尝试在不重新启动 Unity 编辑器的情况下再次运行它,整个编辑器就会冻结。有时需要三次而不是两次,但每次或第三次尝试播放总是会完全冻结 Unity。光标变为旋转的风车。

日志说:

Starting.
(Filename: /Applications/buildAgent/work/d63dfc6385190b60/artifacts/MacEditorGenerated/UnityEngineDebug.cpp Line: 49)
Receiving unhandled NULL exception
Launching bug reporter
Obtained 37 stack frames.
#0  0x00000090019390 in _platform_memmove$VARIANT$sse42

然后堆栈跟踪会调出调用extern函数的函数。

尝试加入正在运行的线程startPlugin会在停止时冻结编辑器。我认为它不应该这样做。毕竟,在那个阶段,循环结束,实例被清理干净。这不是猜测,有明显的副作用:结束循环关闭计算机的摄像头,我可以看到摄像头的灯熄灭了。此外,在调用 startPlugin 返回后,还会在 C# 中发送调试消息。所以毫无疑问,循环已经结束。

每次在 Windows 上都不会删除实例的先前版本都有效。

我做错了什么吗?

我找到了答案。

即使C++内部没有调用线程,我仍然需要在 process 方法结束时调用pthread_exit(this)。这在Windows上不是必需的,但在Mac上是必需的。在那之后,一切都有效。