Проблема проста. Я включаю в свой MFC-проект некие левые .cpp файлы (свои или чужие — не важно), в которых используюся операторы new/delete. Так вот, не линкуется зараза! Не линкуется только со static MFC и говорит о дублировании символов. Очевидно, MFC использует какие-то свои new/delete, которые конфликтуют с new/delete из CRT. Но я не хочу использовать DLL и делать свой release зависимым от mfcXXXX.dll. Я так же не хочу включать stdafx.h в эти cpp-файлы — я могу это сделать в своих файлах, но в конце концов, если я использую что-то чужое, пришедшее, скажем, из Linux, но абсолютно системо-независимое, то все равно проблема остается. Просто не хорошо это — трогать чужой код. Можно включить опцию линкера "Force output", но результат как-то не внушает доверия — об этом же и предупреждения будут. Можно сделать один .cpp файл, включающий stdafx.h и затем — все остальные "левые" .cpp файлы. Это работает, но, согласитесь, выглядит совершенно по-уродски — где идея о раздельной компиляции? Так чего же я хочу? Очень простого — возможности слинковать с MFC другие .cpp файлы, написанные в полном соответствии с индустриальным стандартом C++ без их модификации, а просто включив в проект. Пример здесь: http://www.antigrain.com/customrenderer.zip
Не знаю, может есть каклй-нибудь #define, как в ATL: ATL_MIN_CRT, включение которого приводит примерно к тем же проблемам, за счет уменьшения объема бинарного кода. Нет ли какого аналогичного в MFC, но наоборот, типа #define ПОДРУЖИТЬ_MFC_И_CRT — и настало щщастье .
В общем,
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте McSeem2, Вы писали:
MS>Проблема проста. Я включаю в свой MFC-проект некие левые .cpp файлы (свои или чужие — не важно), в которых используюся операторы new/delete. Так вот, не линкуется зараза! Не линкуется только со static MFC и говорит о дублировании символов. Очевидно, MFC использует какие-то свои new/delete, которые конфликтуют с new/delete из CRT. Но я не хочу использовать DLL и делать свой release зависимым от mfcXXXX.dll. Я так же не хочу включать stdafx.h в эти cpp-файлы — я могу это сделать в своих файлах, но в конце концов, если я использую что-то чужое, пришедшее, скажем, из Linux, но абсолютно системо-независимое, то все равно проблема остается. Просто не хорошо это — трогать чужой код. Можно включить опцию линкера "Force output", но результат как-то не внушает доверия — об этом же и предупреждения будут. Можно сделать один .cpp файл, включающий stdafx.h и затем — все остальные "левые" .cpp файлы. Это работает, но, согласитесь, выглядит совершенно по-уродски — где идея о раздельной компиляции? Так чего же я хочу? Очень простого — возможности слинковать с MFC другие .cpp файлы, написанные в полном соответствии с индустриальным стандартом C++ без их модификации, а просто включив в проект. Пример здесь: http://www.antigrain.com/customrenderer.zip MS>Не знаю, может есть каклй-нибудь #define, как в ATL: ATL_MIN_CRT, включение которого приводит примерно к тем же проблемам, за счет уменьшения объема бинарного кода. Нет ли какого аналогичного в MFC, но наоборот, типа #define ПОДРУЖИТЬ_MFC_И_CRT — и настало щщастье . MS>В общем,
Для конкретного .cpp файла указать в Project Settings закладка C/C++ категория Precompiled Headers: Not using precompiled headers
Есть ключ настроек в Project/Settings/"C/C++" /Yu "stdafx.h" убери его и это (вроде) даст тебе возможность подключать те библиотеки которые тебе требуются и не подключать stdafx.h там где ты не хочешь ...
Насчет подружить не знаю, по моему решением твоей проблемы будет объявить разные namespace для разных файлов. Это конечно не самый элегантный выход, но другого я пока не припомню (вспомню, напишу).
Здравствуйте Vasiliy_Krasnokutsky, Вы писали:
VK>Есть ключ настроек в Project/Settings/"C/C++" /Yu "stdafx.h" убери его и это (вроде) даст тебе возможность подключать те библиотеки которые тебе требуются и не подключать stdafx.h там где ты не хочешь ...
Знаю я про этот ключ.
VK>Насчет подружить не знаю, по моему решением твоей проблемы будет объявить разные namespace для разных файлов. Это конечно не самый элегантный выход, но другого я пока не припомню (вспомню, напишу).
namespace не спасет, поскольку в моих файлах (не связанных с MFC а системно-незавмсимых) используются глобальные, неперегруженные new/delete. Там и так все завернуто в отдельный namespace.
Проблема такая:
Linking...
xilink6: executing 'D:\PROGRA~1\MICROS~2\VC98\Bin\link.exe'
nafxcw.lib(afxmem.obj) : error LNK2005: "void * __cdecl operator new(unsigned int)" (??2@YAPAXI@Z) already defined in LIBCMT.lib(new.obj)
nafxcw.lib(afxmem.obj) : error LNK2005: "void __cdecl operator delete(void *)" (??3@YAXPAX@Z) already defined in LIBCMT.lib(delete.obj)
Release/CustomRenderer.exe : fatal error LNK1169: one or more multiply defined symbols found
Error executing xilink6.exe.
То есть new/delete из afxmem.obj конфликтует с аналогичными из LIBCMT.lib. Если я включаю stdafx.h в мои файлы, конфликта нет — подключаются new/delete из afxmem.obj. Но я-то как раз и не хочу его включать. Ну что за бардак? Нафига было специально для MFC придумывать какие-то специальные new/delete? Я понимаю, для Debug Mode там судя по всему живет bound checker, я с этим могу смириться. Но когда он мне в Release не нужен, конфликт все равно остается. Почему они так CRT не любят?
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.
Здравствуйте McSeem2,
Попробуй включить опцию Project/Settings/Link-General -- Ignore all default libraries, теоретически должно помочь, а выше пропиши свои lib (если надо)
Здравствуйте Vasiliy_Krasnokutsky, Вы писали:
VK>Здравствуйте McSeem2, VK>Попробуй включить опцию Project/Settings/Link-General -- Ignore all default libraries, теоретически должно помочь, а выше пропиши свои lib (если надо)
VK>С Уважением Краснокутский Василий
Не поможет.
Нельзя их честным способом подружить. new/delete переопределены глобально в
библиотеке MFC, файл afxmem.cpp:
Так что единственный способ — это включить MFC-шные кишки, то есть, afx.h.Но это не выход, поскольку, еще раз повторю, я использую не только свои исходники, но и чужие, которые знать ничего не знают ни про какие винды и AFXы и которые я категорически не хочу модифицировать. Дефайна, типа
ATL_MIN_CRT который можно было определить в командной строке компилятора для этого дела не существует. Такие дела. Единственный "честный" выход — это как сейчас — включать все исходники в
один .cpp файл, в начале которого включен stdafx.h.
Сначала я не мог понять, что заставляет компилятор использовать именно тот new, который имплементирован в afxmem.obj а не в CRT. Потом догадался.
Смешно, но условие возможности использования new/delete с MFC — это написать что-то типа:
Как это и сделано в afx.h Тогда компилятор поместит специальную закорючку в obj-файл и ликер будет знать, что искать надо в первую очередь там, а остальное игнорировать. То есть, если убрать это дело из afx.h и вручную подключить в проект соответструющие MFC-библиотеки, то постигнет та же самая беда, даже при использовании только-MFC-и-ничего-более. Вот, блин, клоуны
McSeem
Я жертва цепи несчастных случайностей. Как и все мы.