2010-08-01 2 views
1

Сегодня я попытался получить Редактировать & продолжать работать в моем решении, которое выглядит следующим образом:Несколько проектов C++ .lib для проектов .dll, сбоев Lua!

Game Engine .LIB < - Игра .LIB < - Редактор .exe

     <- Server .exe 

         <- Client .exe 

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

Таким образом, я получил кучу «__declspec (dllexport)» там и т. Д. Работает просто отлично, он работает!

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

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

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

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

EDIT: Больше не было сбоев после того, как я превратил Lua в DLL. Прежде чем я попробовал это, я также перекомпилировал статику с тем же компилятором, что и все другие проекты, и я дважды проверил библиотеки времени выполнения, и они все одинаковы, и я привязываюсь к правильным библиотекам debug/release. Мне все еще интересно, что здесь происходит.

Иметь хороший день,

Antoon

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

ответ

3

Вы писали:

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

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

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

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

+0

Это ответ, спасибо, сэр! Да, я статически привязывал его к Engine.dll и Game.dll, потому что первоначально Engine.lib связывает его, и Game.lib автоматически наследует символы, конечно. И да, превратив Lua в dll, это исправлено. Очень интересная ошибка =). – Xilliah

0

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

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

+0

Редактировать & Продолжить не поддерживается для статических библиотек в Visual Studio C++ – Xilliah

+0

Спасибо, я пропустил часть статических библиотек. Я вообще не работаю с ними. –

1

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

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

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

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

+0

Интересно, потому что я уверен, что Луа был тем, кто выделил и освободил память. И библиотеки времени выполнения были настроены одинаково, и все проекты, включая Lua, были скомпилированы с одним и тем же компилятором. Возможно, один или два варианта были разными. Мне всегда сложно сравнивать параметры компилятора в VS. – Xilliah

0

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

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

  • Debug Multithread DLL (/ MDd) для отладки строит
  • Release многопоточных DLL (/ MD) для выпуска строит

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

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

Смежные вопросы