views:

282

answers:

1

Hello :)

I'm a bit confused on setting up the boost test library. Here is my code:

#include "stdafx.h"
#define BOOST_TEST_DYN_LINK
#define BOOST_TEST_MODULE pevUnitTest
#include <boost/test/unit_test.hpp>

BOOST_AUTO_TEST_CASE( TesterTest )
{
    BOOST_CHECK(true);
}

My compiler generates the wonderfully useful error message:

1>MSVCRTD.lib(wcrtexe.obj) : error LNK2019: unresolved external symbol _wmain referenced in function ___tmainCRTStartup
1>C:\Users\Billy\Documents\Visual Studio 10\Projects\pevFind\Debug\pevUnitTest.exe : fatal error LNK1120: 1 unresolved externals

It seems that the Boost::Test library is not generating a main() function -- I was under the impression it does this whenever BOOST_TEST_MODULE is defined. But ... the linker error continues.

Any ideas?

Billy3

EDIT: Here's my code to work around the bug described in the correct answer below:

#include "stdafx.h"
#define BOOST_TEST_MODULE pevUnitTests
#ifndef _UNICODE
#define BOOST_TEST_MAIN
#endif
#define BOOST_TEST_DYN_LINK
#include <boost/test/unit_test.hpp>

#ifdef _UNICODE

int _tmain(int argc, wchar_t * argv[])
{
    char ** utf8Lines;
    int returnValue;

    //Allocate enough pointers to hold the # of command items (+1 for a null line on the end)
    utf8Lines = new char* [argc + 1];

    //Put the null line on the end (Ansi stuff...)
    utf8Lines[argc] = new char[1];
    utf8Lines[argc][0] = NULL;

    //Convert commands into UTF8 for non wide character supporting boost library
    for(unsigned int idx = 0; idx < argc; idx++)
    {
     int convertedLength;
     convertedLength = WideCharToMultiByte(CP_UTF8, NULL, argv[idx], -1, NULL, NULL, NULL, NULL);
     if (convertedLength == 0)
      return GetLastError();
     utf8Lines[idx] = new char[convertedLength]; // WideCharToMultiByte handles null term issues
     WideCharToMultiByte(CP_UTF8, NULL, argv[idx], -1, utf8Lines[idx], convertedLength, NULL, NULL);
    }

    //From boost::test's main()
    returnValue = ::boost::unit_test::unit_test_main( &init_unit_test, argc, utf8Lines );
    //End from boost::test's main()

    //Clean up our mess
    for(unsigned int idx = 0; idx < argc + 1; idx++)
     delete [] utf8Lines[idx];
    delete [] utf8Lines;

    return returnValue;
}

#endif

BOOST_AUTO_TEST_CASE( TesterTest )
{
    BOOST_CHECK(false);
}

Hope that's helpful to someone.

Billy3

+3  A: 

I think the problem is that you're using VC10.

It has a fun little bug where, when Unicode is enabled, it requires the entry point to be wmain, not main. (Older versions allowed you to use both wmain and main in those cases).

Of course this will be fixed in the next beta, but until then, well, it's a problem. :)

You can either downgrade to VC9, disable Unicode, or try manually setting the entry point to main in project properties.

Another thing that might work is if you define your own wmain stub, which calls main. I'm pretty sure this is technically undefined behavior, but as a workaround for a compiler bug in an unreleased compiler it might do the trick.

jalf
Yup -- that's it. The strange thing is --- I'm not using VC10 -- I've set the toolchain to use VS2008 -- I'm only using VS2010 for it's editor. Thank you for your psychic debugging. I'm working on the last option now and will post here when it's done. (App is unicode -- no test is worth it in ANSI mode)
Billy ONeal
Added my code above in case you're interested.
Billy ONeal