Какие-нибудь улучшения в GCC / Windows DLL / C ++ STL? - PullRequest
2 голосов
/ 04 февраля 2009

Вчера я столкнулся с довольно неприятным сбоем при использовании библиотек DLL, скомпилированных с GCC под Cygwin. По сути, как только вы запускаете отладчик, вы можете оказаться в ловушке отладки, вызванной тем, что RtlFreeHeap () получает адрес для чего-то, что он не выделил.

Это известная ошибка с GCC 3.4 на Cygwin. Ситуация возникает из-за того, что библиотека libstdc ++ включает «умную» оптимизацию для пустых строк. Я избавляю вас от деталей (см. Ссылки в этом посте), но всякий раз, когда вы выделяете память в одной DLL для объекта std :: string, который «принадлежит» другой DLL, вы в конечном итоге выделяете одну кучу для освобождения, полученную из еще одна куча. Следовательно, SIGTRAP в RtlFreeHeap () .

Существуют и другие проблемы, возникающие при выдаче исключений через границы DLL.

Это делает GCC 3.4 в Windows неприемлемым решением, как только ваш проект основан на DLL и STL. У меня есть несколько вариантов, чтобы пройти мимо этого параметра, многие из которых очень трудоемки и / или раздражают:

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

У кого-нибудь есть новости по этому поводу? Я не могу найти четкого объявления о том, что это исправлено (ошибка по-прежнему помечена как "назначенная"), кроме одного комментария к Радио трекер ошибок GNU .

Спасибо!

1 Ответ

1 голос
/ 07 февраля 2009

Основная проблема, с которой вы сталкиваетесь, заключается в том, что C ++ никогда не задумывался как компонентный язык. Это было действительно разработано, чтобы использоваться, чтобы создать законченные автономные приложения. Такие вещи, как разделяемые библиотеки и другие подобные механизмы, были созданы поставщиками самостоятельно. Подумайте об этом примере: предположим, что вы создали компонент C ++, который возвращает объект C ++. Как компонент C ++ знает, что он будет использоваться вызывающей стороной C ++? И если вызывающая программа является приложением C ++, почему бы просто не использовать библиотеку напрямую?

Конечно, приведенная выше информация не очень вам помогает.

Вместо этого я бы создал разделяемые библиотеки / библиотеки DLL, чтобы вы следовали нескольким правилам:

  1. Любой объект, созданный компонентом, также уничтожается этим же компонентом.
  2. Компонент может быть безопасно выгружен после уничтожения всех созданных им объектов.

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

...