Мой плагин C++ Unity запускается в редакторе один раз, но не дважды

У меня есть плагин, который вызывает код C++. Когда игра запускается, она вызывает эту функцию extern C++:

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

Метод process запускает бесконечный цикл, который обрабатывает данные и продолжается до тех пор, пока элемент keepRunning имеет значение true. Поскольку он запускает бесконечный цикл и блокируется, этот метод вызывается в собственном потоке.

Когда игра заканчивается, я запускаю этот метод extern из C#:

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, приводит к зависанию редактора при остановке. Я не думаю, что это должно делать это. Ведь на этом этапе цикл завершается и экземпляр очищается. Это не догадки, есть видимые побочные эффекты: завершение цикла выключает камеру компьютера, и я вижу, как гаснет свет камеры. Также отладочное сообщение отправляется в C# после возврата вызова startPlugin. Так что можно не сомневаться, что петля закончилась.

Предыдущая версия, которая не удаляет экземпляр, всегда работает в Windows.

Я делаю что-то явно не так?


person eje211    schedule 30.12.2014    source источник


Ответы (1)


Я нашел свой ответ.

Несмотря на то, что внутри C++ не вызывается ни один поток, мне все равно нужно вызывать pthread_exit(this) в конце метода process. В Windows это не обязательно, но на Mac есть. После этого все работает.

person eje211    schedule 31.12.2014