Несколько C ++ .lib проектов в .dll проекты, Lua падает! - PullRequest
1 голос
/ 02 августа 2010

Сегодня я попытался заставить Edit & Continue работать в моем решении, которое выглядит следующим образом:

Game Engine .lib <- Game .lib <- Editor .exe </p>

                        <- Server .exe

                        <- Client .exe

Что хорошо работает.Но теперь я хотел превратить движок и игру .libs в .dll, чтобы я мог использовать функцию Edit & Continue в Visual Studio C ++.

Так что я получил кучу "__declspec (dllexport)" втам и т. д. работает просто отлично, работает!

Но в определенных ситуациях вылетает.На самом деле, это всегда происходит сбой в функции Lua, связанной с освобождением памяти.

Движок и игра работают с Lua, у них обоих есть свои статические функции интерфейса C ++.

Яне уверен, но я полагаю, что .dll немного похож на .exe без основной функции, и у каждого есть своя память.Поэтому, когда, например, Game.dll заставляет Lua выделить некоторую память, а Engine.dll заставляет Lua снова ее освободить, бум!Правильно?

Есть идеи, как это решить?Конечно, Engine.dll должен отвечать за Lua, но Game.dll должен иметь возможность расширять интерфейс новыми статическими функциями.

РЕДАКТИРОВАТЬ: больше не было сбоев после того, как я превратил сам Lua в .dll,Прежде чем я попробовал это, я также перекомпилировал статику с тем же компилятором, что и все другие проекты, и я дважды проверил библиотеки времени выполнения, и они все одинаковые, и я ссылаюсь на правильные библиотеки отладки / выпуска.Мне все еще интересно, что здесь происходит.

Хорошего дня,

Antoon

PS Почему у меня нет контроля над возвратами в Stackoverflow?

Ответы [ 4 ]

3 голосов
/ 03 августа 2010

Вы писали:

Движок и игра работают с Lua, у них обоих есть свои статические функции интерфейса C ++.

Это дает мне возможностьчто каждый движок и игра индивидуально статически связаны с копией Lua.

Если бы это было правдой, то это именно то, что вы ожидаете, если бы состояние Lua было создано однимкопии были переданы другому.Типичный результат - испортить состояние памяти и сломать распределитель.Основная причина в том, что реализация значения nil зависит от адреса чего-либо внутри движка Lua.Вторая копия механизма, связанная с тем же процессом, будет иметь другой адрес, обозначающий nil.Этот путь в конечном итоге приводит к безумию.

Конечно, если игра и движок используют одну копию интерпретатора Lua (скажем, с помощью LUA51.DLL), то я лаю не на том дереве.

1 голос
/ 02 августа 2010

Может быть, это только я, но я нахожу информацию, которую вы включили, немного скудной.Поскольку вы упомянули, что ваши проблемы связаны с распределением памяти через границы модуля, я бы порекомендовал вам следующую статью:

http://blogs.msdn.com/b/oldnewthing/archive/2006/09/15/755966.aspx

По сути, память должна быть освобождена с использованием того жераспределитель, который использовался для его выделения, то есть не смешивать новый / свободный - но это также означает, что вам не следует выделять и освобождать память через границы модулей, так как модули могут быть скомпилированы с разными настройками, например, распределитель отладки может отличатьсяот той, которая использовалась в версии выпуска, или она может отличаться из-за разных версий используемой среды выполнения (другой выпуск, другой поставщик и т. д.)

В большинстве случаев безопаснее всего просто обрабатывать выделение памятив одном модуле, предоставляя согласованный интерфейс, который используется каждым другим модулем в вашем проекте.

0 голосов
/ 02 августа 2010

Я полагаю, одна DLL / EXE распределила память, а другая пытается освободить ее и вылетает.

Решение состоит в том, чтобы убедиться, что все ваши двоичные файлы скомпилированы с:

  • Отладка многопоточной DLL (/ MDd) для отладочных сборок
  • Релиз многопоточной DLL (/ MD) для релизных сборок

И, конечно же, убедитесь, что все ваши DLL / EXE были скомпилированы с одинаковым компилятором и параметрами ...

Это единственный способ для двоичных файлов (EXE и DLL) в одном и том же процессе совместно использовать свои распределители памяти.

0 голосов
/ 02 августа 2010

Почему вы думаете, что вам нужно отредактировать DLL и продолжить? Насколько я использовал, он прекрасно работает и на исполняемых файлах. Была ли какая-то конкретная ошибка, которая мешает вам ее использовать?

DLL не получают свой собственный сегмент памяти, но они могут использовать свой собственный механизм распределения, который может быть несовместимым. Убедитесь, что все библиотеки DLL и основная программа связаны с одной и той же версией библиотеки времени выполнения C (отладка или выпуск, многопоточная или не многопоточная, и с одинаковым номером версии).

...