Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > С/С++: Кроссплатформенное программирование, Qt/Gtk+/wxWidgets > Qt + TCHAR = unresolve external


Автор: null56 20.10.2010, 13:44
Всем привет
Проекты Qt собираются под студией
Проблема:
Есть либа (static lib), из которой черпаются классы с методами. Все линкуется кроме методов, аргументы которых имеют тип TCHAR или аналогичные макросы винды
Линковщик выводит следующее
Код

unresolved external symbol "public: bool __thiscall filesystem::FileReader::open(unsigned short const  *,unsigned long,unsigned long,unsigned long)"

хотя прототип функции имеет вид
Код

bool open(LPCTSTR lpFileName, ...

я так понял, что проблема как раз в этих макросах, Qt почему - то считает, что это не wchar_t

Вопросы:
- как решить эту проблему?
- и реально ли вообще это сделать без пересборки либы?

заранее благодарен за помощь

ЗЫ: при компиляции в проекте присутствуют
Код

_UNICODE,UNICODE,WIN32,QT_LARGEFILE_SUPPORT;QT_THREAD_SUPPORT;QT_CORE_LIB;QT_GUI_LIB;QT_SQL_LIB

Автор: borisbn 20.10.2010, 13:50
скорее всего эта твоя либа (static lib) скомпилирована без поддержки UNICODE, а Qt - с ней.
Несмотря на то, что в прототипе указано
Цитата

open(LPCTSTR lpFileName, ...

в самой lib-ине код - неюникодовский.
решение видится такое:
1-й вариант: для h-ника с описанием прототипа отключить UNICODE
2-й вариант: скомпилировать lib-ину с поддержкой UNICODE
3-й вариант: уйти от этих типов TSTR и указывать явно char * или wchar_t *

для 2-го и 3-го вариантов нужно перекомпилировать библиотеку.

Автор: null56 20.10.2010, 13:51
ща проверю

Добавлено @ 13:53
вы были правы... я бы долго сидел думал... спасибо вам

Ответ:  в либе отсутсвовали макросы UNICODE, видимо кто - то их забыл выставить или нарочно убрал )

Автор: null56 20.10.2010, 15:19
поторопился я радоваться
http://ipicture.ru/uploads/101020/VsmT4LDr4E.png
либа тоже юникодовая судя по всему
ошибки не изчезли...

Добавлено @ 15:21
перекомпилировать либу можно, только вопрос как, чтобы таких косяков не было


Автор: borisbn 20.10.2010, 15:53
Цитата(null56 @  20.10.2010,  15:19 Найти цитируемый пост)
перекомпилировать либу можно, только вопрос как, чтобы таких косяков не было


Цитата(borisbn @  20.10.2010,  13:50 Найти цитируемый пост)
3-й вариант: уйти от этих типов TSTR и указывать явно char * или wchar_t *


и вообще в интерфейс lib-ины и dll-ки ( т.е. бинарника ) лучше не выносить нестандартные типы, потому, что эти типы у тебя и у пользователя этой либины могут отличаться в зависимости от настроек компилятора, версии SDK и т.п. Это  же относится и к std::xxx

Автор: null56 20.10.2010, 15:58
я только что заменил в классе типы аргументов на wchar_t, ошибка не прошла

Автор: 586 20.10.2010, 16:16
null56,  попробуй поменять настройку в проекте: Project Properties -> Configuration Properties -> C/C++ -> Language -> Treat wchar_t as Built-in Type.

Автор: null56 20.10.2010, 16:22
вот как раз только что сделал это в режим Yes
получил 
Цитата

LINK : warning LNK4098: defaultlib 'LIBCMTD' conflicts with use of other libs; use /NODEFAULTLIB:library
admin_offline.obj : error LNK2019: unresolved external symbol "__declspec(dllimport) public: class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > __thiscall QString::toStdWString(void)const " (__imp_?toStdWString@QString@@QBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@XZ) referenced in function "protected: void __thiscall admin_offline::AdminOffline::choose_key_file(void)" (?choose_key_file@AdminOffline@admin_offline@@IAEXXZ)
create_task_dialog.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > __thiscall QString::toStdWString(void)const " (__imp_?toStdWString@QString@@QBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@XZ)
result_widget.obj : error LNK2001: unresolved external symbol "__declspec(dllimport) public: class std::basic_string<wchar_t,struct std::char_traits<wchar_t>,class std::allocator<wchar_t> > __thiscall QString::toStdWString(void)const " (__imp_?toStdWString@QString@@QBE?AV?$basic_string@_WU?$char_traits@_W@std@@V?$allocator@_W@2@@std@@XZ)


Добавлено через 11 минут и 23 секунды
с этой опцией, я так понял, нельзя теперь пользоваться методом?
Код

toStdWString

Автор: 586 20.10.2010, 16:33
Попробуй теперь отключить эту опцию, и в проекте, вместо wchar_t используй unsigned short. Если не будет компилироваться, то просто short.

Добавлено
Хотя нет. то не поможет. Без этой опции, wchar_t равен unsigned short.

Автор: null56 20.10.2010, 16:44
завелось, но либы в таком виде оставлять не могу ( чего предолжите еще?

Автор: borisbn 20.10.2010, 16:46
Цитата(null56 @  20.10.2010,  16:44 Найти цитируемый пост)
завелось
 как ?

Автор: null56 20.10.2010, 16:48
изменил типы параметров в методах либы
было
Код

openr(TCHAR * keyFile)

стало
Код

openr(unsigned short * keyFile)


Автор: 586 20.10.2010, 17:20
Цитата(null56 @  20.10.2010,  17:48 Найти цитируемый пост)
изменил типы параметров в методах либы
было
Код
openr(TCHAR * keyFile)


стало
Код
openr(unsigned short * keyFile)

А "Treat wchar_t as Built-in Type" включён?

Автор: borisbn 20.10.2010, 17:28
Ещё один момент. std::wstring ( возвращается toStdWString ), откомпилированный в библиотеках Qt, и std::wstring, откомпилированный в твоём проекте, совпадают только по интерфейсу. гарантии, что они будут полностью совпадать по реализации - нет. Т.о. см. след. код с комментариями:
Код

// пример класса std::wstring, компилируемого в библиотеке Qt
class std::wstring ...
public:
  std::wstring & std::wstring( const std::wstring & other ) {
// копирование данных из other в *this
  }
  void foo2();
protected:
  unsigned short * m_data;
  size_t m_dataLen;
}


Код

// пример класса std::wstring, компилируемого в твоей программе
class std::wstring ...
public:
  std::wstring & std::wstring( const std::wstring & other ) {
// копирование данных из other в *this
  }
  void foo2();
protected:
  unsigned short * m_data;
}


Код

// твой код
QString str;
std::wstring w = str.toStdWString(); // как ты думаешь, что здесь произойтёт ?


P.S. Всё это не относится к тому случаю, если ты собирал библиотеки Qt у себя своим компилятором со своим SDK, а только, если установил библиотеки с сайта.

Автор: null56 20.10.2010, 17:34
Цитата(586 @  20.10.2010,  17:20 Найти цитируемый пост)
А "Treat wchar_t as Built-in Type" включён? 

No(/Zc:wchar_t-)

Цитата(borisbn @  20.10.2010,  17:28 Найти цитируемый пост)

P.S. Всё это не относится к тому случаю, если ты собирал библиотеки Qt у себя своим компилятором со своим SDK, а только, если установил библиотеки с сайта. 

я ставил собранные библиотеки с сайта

Автор: 586 20.10.2010, 18:04
Цитата(null56 @  20.10.2010,  18:34 Найти цитируемый пост)
Цитата(586 @  20.10.2010,  18:20 Найти цитируемый пост)
А "Treat wchar_t as Built-in Type" включён? 

No(/Zc:wchar_t-)

Если он выключен, то
  wchar_t равен unsigned short
  TCHAR равен unsigned short (при директиве UNICODE)
  LPCTSTR равен const unsigned short* (при директиве UNICODE)
и следовательно, можно так написать:
Код
bool open(TCHAR* lpFileName

и ошибок по идее быть не должно.


Цитата(null56 @  20.10.2010,  18:34 Найти цитируемый пост)
Цитата(borisbn @  20.10.2010,  18:28 Найти цитируемый пост)
P.S. Всё это не относится к тому случаю, если ты собирал библиотеки Qt у себя своим компилятором со своим SDK, а только, если установил библиотеки с сайта. 
я ставил собранные библиотеки с сайта

плоховато.

Автор: null56 20.10.2010, 21:21
выключен в проекте Qt, включен в либе... и как мне поступить?
либой не только из Qt проектов пользуются.


Автор: null56 20.10.2010, 21:45
вообще в проекте я не использую ни одной строки из stl, все QString, есть только некоторые функции из библиотек, которым необходим указатель на начало строки, вот там как раз и задействуется, что - то типа этого
Код

wchar_t * p = toStdWString().c_ctr();

не думаю, что здесь есть какие моменты для конфликтов реализаций

Автор: borisbn 20.10.2010, 22:33
Цитата(null56 @  20.10.2010,  21:45 Найти цитируемый пост)
не думаю, что здесь есть какие моменты для конфликтов реализаций

не уверен, тем более, что 
Цитата(null56 @  20.10.2010,  17:34 Найти цитируемый пост)
я ставил собранные библиотеки с сайта

а вместо этого
Цитата(null56 @  20.10.2010,  21:45 Найти цитируемый пост)
wchar_t * p = toStdWString().c_ctr();

лучше юзать
Код

const ushort * p = str.toUtf16();


я почему упорствую - уже сталкивался с подобной проблемой. Там была разница даже не в версии SDK, а в Multithread/Singlethread-версиях CRT.

Резюме ( я для себя вывел такое правило ):
собираешь библиотеки сам или компилируешь все исходники - используй какие хочешь классы, типы и т.п.
хочешь, чтобы твои ( или Qt-шные ) программные модули использовались как бинарники - используй в интерфейсах только стандартные ( POD ) типы - const char *, int, bool и т.п.

P.S. А если ты завтра установишь SP на студию, который изменит твой std::xxx ?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)