Каково предпочтительное кросс-платформенное «основное» определение с использованием boost::program_options?

Я пытаюсь разработать кроссплатформенное приложение с использованием С++ с повышением.

Обычно я программирую в среде *nix, где я всегда определял «main» следующим образом:

int main( const int argc, const char* argv[] )
{
...
}

Для этого приложения я начинаю в среде Windows, используя Visual Studio 2003.

Когда я пытаюсь использовать boost::program_options с этим определением, я получаю ошибки компиляции из program_options::store:

po::options_description desc("Supported options");
desc.add_options()...;
po::variables_map vm;
po::store(po::parse_command_line(argc, argv, desc), vm);

Ошибка:

main.cpp(46) : error C2665: 'boost::program_options::store' : none of the 2 overloads can convert parameter 1 from type 'boost::program_options::basic_parsed_options<charT>'
    with
    [
        charT=const char
    ]
    c:\boost_1_38_0\boost\program_options\variables_map.hpp(34): could be 'void boost::program_options::store(const boost::program_options::basic_parsed_options<charT> &,boost::program_options::variables_map &,bool)'
    with
    [
        charT=char
    ]
    c:\boost_1_38_0\boost\program_options\variables_map.hpp(43): or       'void boost::program_options::store(const boost::program_options::basic_parsed_options<wchar_t> &,boost::program_options::variables_map &)'
    while trying to match the argument list '(boost::program_options::basic_parsed_options<charT>, boost::program_options::variables_map)'
    with
    [
        charT=const char
    ]

Я попытался заставить функцию wchar_t определить main следующим образом:

int main( const int argc, wchar_t* argv[]){
...
}

Затем он компилируется, но я получаю ошибки ссылок:

main.obj : error LNK2019: unresolved external symbol "void __cdecl boost::program_options::store(class boost::program_options::basic_parsed_options<unsigned short> const &,class boost::program_options::variables_map &)"  referenced in function _main
main.obj : error LNK2019: unresolved external symbol "public: __thiscall boost::program_options::basic_parsed_options<unsigned short>::basic_parsed_options<unsigned short>(class boost::program_options::basic_parsed_options<char> const &)"  referenced in function "public: class boost::program_options::basic_parsed_options<unsigned short> __thiscall boost::program_options::basic_command_line_parser<unsigned short>::run(void)" 
main.obj : error LNK2019: unresolved external symbol "class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > __cdecl boost::program_options::to_internal(class std::basic_string<unsigned short,struct std::char_traits<unsigned short>,class std::allocator<unsigned short> > const &)"  referenced in function "class std::vector<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::allocator<class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> > > > __cdecl boost::program_options::to_internal<class std::basic_string<unsigned short,struct std::char_traits<unsigned short>,class std::allocator<unsigned short> > >(class std::vector<class std::basic_string<unsigned short,struct std::char_traits<unsigned short>,class std::allocator<unsigned short> >,class std::allocator<class std::basic_string<unsigned short,struct std::char_traits<unsigned short>,class std::allocator<unsigned short> > > > const &)" 

Наконец, если я вернусь к настройке основного определения по умолчанию в Visual Studio, она скомпилируется и свяжется:

int main( const int argc, _TCHAR* argv[]){
...
}

Итак, это хорошо для Windows, но будет ли это работать, когда я попытаюсь перенести его на * nix? Эти системы обычно определяют тип _TCHAR? Я лично не сталкивался.

Как правильно определить main для работы в Windows и *nix, а также для работы с библиотекой boost::program_options?


person Adam Holmberg    schedule 30.06.2009    source источник


Ответы (2)


Кажется, это проблема, связанная с константностью. Пытаться:

int main( int argc, char* argv[] )
{
  // ...
}
person e.tadeu    schedule 30.06.2009
comment
Спасибо, это сработало. В этой заметке - может кто-нибудь объяснить мне, почему argc и argv не должны быть константами в main? - person Adam Holmberg; 01.07.2009
comment
Потому что так говорит стандарт С++. Обратите внимание, что все примеры библиотек также используют правильную подпись. - person Vladimir Prus; 01.07.2009
comment
Думаю, мне следовало спросить, почему стандарт не определяет их как константы? Мне кажется, что эти вещи не должны меняться в контексте «основного». - person Adam Holmberg; 01.07.2009
comment
Изменение argv[0] изменяет способ отображения вашей программы в выводе ps - person Gaius; 29.09.2011

int main() и int main(int argc, char* argv[]) (также известные как int main(int argc, char** argv)) — это подписи, одобренные стандартами C++.

VisualStudio пытается быть полезным множеством безумных способов, в том числе пытаясь определить, (1) вы хотите main() или WinMain() и (2) решить, хотите ли вы char или wchar_t. Если VisualStudio не считает, что вы работаете в консольном приложении, вам может потребоваться вызвать split_winmain().

Если вы хотите принудительно использовать chars (что я бы рекомендовал), вам может потребоваться #undef UNICODE.

person Max Lybbert    schedule 30.06.2009