Boost::Test -- generation of Main()? - c++

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

I think the problem is that you're using the VC10 beta.
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.

Related

C file cannot be compiled in c++ Visual Studio

For some reason I can no longer compile a c file in my c++ clr console application. It worked before without the clr support, I also switched my project to compile as /TP still not working. Any help would be greatly appreciated.
Error
Severity Code Description Project File Line Suppression State
Error C2664 'int strcmp(const char *,const char *)': cannot convert argument 1 from 'WCHAR [260]' to 'const char *'
snowkill.c
#include "snowkill.h"
void killProcessByName(WCHAR *filename)
{
HANDLE hSnapShot = CreateToolhelp32Snapshot(TH32CS_SNAPALL, NULL);
PROCESSENTRY32 pEntry;
pEntry.dwSize = sizeof(pEntry);
BOOL hRes = Process32First(hSnapShot, &pEntry);
while (hRes)
{
if (strcmp(pEntry.szExeFile, filename) == 0)
{
HANDLE hProcess = OpenProcess(PROCESS_TERMINATE, 0,
(DWORD)pEntry.th32ProcessID);
if (hProcess != NULL && pEntry.th32ProcessID != GetCurrentProcessId())
{
TerminateProcess(hProcess, 9);
CloseHandle(hProcess);
}
}
hRes = Process32Next(hSnapShot, &pEntry);
}
CloseHandle(hSnapShot);
}
snowkill.h
#pragma once
#include "stdafx.h"
#include <windows.h>
#include <process.h>
#include <Tlhelp32.h>
#include <winbase.h>
#include <string.h>
#ifdef __cplusplus
extern "C" {
#endif
void killProcessByName(WCHAR *filename);
#ifdef __cplusplus
}
#endif
main.cpp
#include "stdafx.h"
#include "snowkill.h"
#include "motion.h"
#include "info.h"
#include "flushsound.h"
#include "snowserial.h"
using namespace System;
bool on() {
return true;
}
bool off() {
return false;
}
int main()
{
listenoncommport();
for (;;) {
string onoff = checkfile();
if (onoff == "1")
{
//detected();
}
else
{
WCHAR *proccc = L"firefox.exe";
killProcessByName(proccc);
//notdetected();
}
Sleep(5000);
}
return 0;
}
You could change every instance of WCHAR to TCHAR so text setting is "generic", or as already mentioned, change the project property character set to be Unicode only.
void killProcessByName(TCHAR *filename)
/* ... */
if (_tcscmp(pEntry.szExeFile, filename) == 0) /* replaced strcmp */
/* ... */
#include <windows.h> /* needed in order to use TEXT() macro */
/* ... */
TCHAR *proccc = TEXT("firefox.exe"); /* TEXT() is a <windows.h> macro */
Use TCHAR type everywhere if the functions involved are not WCHAR specific. That would allow project setting to build either ANSI/ASCII (not set) or Unicode.
Note that Process32First and Process32Next use TCHAR.
This is mostly for legacy, since Windows 2000 and later API functions use Unicode internally, converting ANSI/ASCII to Unicode as needed, while Windows NT and older API functions use ANSI/ASCII.
However, typically many or most text files (such as source code) are ANSI/ASCII and not Unicode, and it's awkward to have to support Unicode for Windows API and then ANSI/ASCII for text files in the same program, and for those projects I use ANSI/ASCII.
By using the TCHAR based generic types, I can share common code with projects that use Unicode and with projects that use ANSI/ASCII.
The error message is clear: you have an error at this precise line:
if (strcmp(pEntry.szExeFile, filename) == 0)
Because your arguments are not of char* type as expected by strcmp but WCHAR* types. You should use wcscmp instead, which is basically the same function, but working with wchar_t* type.
szExeFile in tagPROCESSENTRY32 is declared as TCHAR, which will be a 1-byte char when compiling with Character Set set to 'Not Set' or 'Multibyte'. Set Character Set in your project settings to Use Unicode Character Set to fix the problem.
Also, use wcscmp to compare WCHAR types.

NetUserChangePassword C++

I would like to change user password on my Windows 7 PC using C++.
But when I compile it gets error:
undefined reference to 'NetUserChangePassword'
[Error] ld returned 1 exit status.`
How can I fix it?
Here is the MSDN page with the NetUserChangePassword function:
#ifndef UNICODE
#define UNICODE
#endif
#pragma comment(lib, "netapi32.lib")
#include <iostream>
#include <stdio.h>
#include <windows.h>
#include <lm.h>
bool ChangeUserPassword(LPCWSTR OldPassword, LPCWSTR NewPassword)
{
NET_API_STATUS nStatus;
LPTSTR lp = new TCHAR[256];
DWORD dw = 256;
GetUserName(lp, &dw);
nStatus = NetUserChangePassword(NULL, lp, OldPassword, NewPassword);
delete[] lp;
if (nStatus == NERR_Success)
return true;
return false;
}
int main(int argc, char** argv)
{
LPCWSTR Old_P = L"C";
LPCWSTR New_P = L"D";
ChangeUserPassword(Old_P, New_P);
return 0;
}
I tried to link to the project the winapi32.dll in two ways
i tried to add using the project option
i tried to add following line
HINSTANCE hInst = LoadLibrary( L"C:\\Windows\\System32\\netapi32.dll ");
but i get always the same error
The requirements section of the MSDN topic you linked to states that you must link the Netapi32.lib library. That is the step that you have missed and explains the missing external error.
As to how to resolve the problem it is hard to say for sure. You are not using the MS compiler and so the #pragma approach won't work. Consult the docs for your compiler/linker to work out how to link this library.
It looks like you are using a GCC based compiler and so need to add -lnetapi32 to the options.

Allegro4/C++ giving error

I'm using the following code (Allegro 4, C++), and getting the following error:
#include <allegro.h>
//defines
#define MODE GFX_SAFE
#define WIDTH 640
#define HEIGHT 480
int main (void)
{
int ret;
int counter;
//initialize allegro
allegro_init();
install_keyboard();
install_timer();
srand(time(NULL));
//set up screen
//set video mode
ret = set_gfx_mode(MODE, WIDTH, HEIGHT, 0, 0);
if (ret != 0)
allegro_message(allegro_error);
allegro_exit();
return 0;
}
Error:
1>MSVCRTD.lib(crtexe.obj) : error LNK2019: unresolved external symbol _main referenced in function ___tmainCRTStartup
All the previous answers regarding that error tell me to switch to "Console" from "Windows"; but I already have "Console" in Properties->Linker->System->Subsystem.
If you don't have an answer, I'd be happy with something I could do to help narrow down the problem: I've used Allegro with C, but I want to use C++ to take advantage of OOP, and so I still have a lot of work to do.
Update:
#include <iostream>
#include <allegro.h>
using namespace std;
int main ()
{
cout << "Hello World";
return 0;
}
doesn't work, but
#include <iostream>
using namespace std;
int main ()
{
cout << "Hello World";
return 0;
}
does.
Now what? Answer: Start with Empty project.
Update2: restarted with an empty project, same code. First block (alleg.lib in linker, but allegro.h not included) works, second code (allegro.h included) doesn't. However, the bug is different:
1>LINK : fatal error LNK1561: entry point must be defined
What now?
Edit^2:Ignore all the following: I forgot to go back to including Allegro. It works now. Thanks everyone for the answers.
Edit: Adding:
END_OF_MAIN()
or
int END_OF_MAIN()
give the error "fatal error C1004: unexpected end-of-file found"
You are getting the error because you are attempting to integrate allegro into a project that is non-empty.
You must create the project as an EMPTY PROJECT type:
New... > Project... > Visual C++ > Empty Project
--EDIT FOR SECOND ERROR--
You must append END_OF_MAIN() after the closing brace of int main():
int main() {
//...
}
END_OF_MAIN()

Cannot get error code from GetPrivateProfileString

Here is my code.
char BPP[5];
int result, err;
result = GetPrivateProfileStringA("abc", "cba", NULL, BPP, 5, "D:\\aefeaf.ini"); // result = 0
result = _get_errno(&err); // result = 0, err = 0
result = GetLastError(); // result = 0
And description from MSDN: In the event the initialization file specified by lpFileName is not found, or contains invalid values, this function will set errorno with a value of '0x2' (File Not Found). To retrieve extended error information, call GetLastError.
Last parameter is random, the file is not existed. But GetLastError() still return 0. Could someone explain to me why it didn't return 2?
EDIT: As #JochenKalmbach suggest, I ensure my project is not using C++/CLI. And #claptrap said that errorno is a typo (it should be errno), I add _get_errno to my code above. But still, all the error code return is 0. Any help is much appreciated.
Hopefully you are not using C++/CLI... this will mess up the value of "GetLastError" because the code internally uses "IJW" (it just works) and does a bunch of Win32 operations....
FOr native applications, this works as expected:
#include <stdio.h>
#include <tchar.h>
#include <Windows.h>
#include <crtdbg.h>
int _tmain(int argv, char *argc[])
{
char szStr[5];
int result = GetPrivateProfileStringA("abc", "cba", NULL, szStr, 5, "D:\\aefeaf.ini");
_ASSERTE(result == 0);
result = GetLastError();
_ASSERTE(result == 2);
}
If you are using C++/CLI, then you should surround the method with
#pragma managed(push, off)
// Place the method here
#pragma managed(pop);

fatal error: strtok_r.h: No such file or directory (while compiling tesseract-ocr-3.01 in MinGW)

I'm compiling tesseract-ocr-3.01 in MinGW, and I'm getting this error ambigs.cpp:31:22: fatal error: strtok_r.h: No such file or directory
This is the code where the error is:
#ifdef WIN32
#ifndef __GNUC__
#define strtok_r strtok_s
#else
#include "strtok_r.h"
#endif /* __GNUC__ */
#endif /* WIN32 */
Edit
I found this feature request to add strtok_r.h to MinGW. From the comments there:
strtok_r() is an optional POSIX function, required only for
implementations which support POSIX threads. MinGW does not support
POSIX threads; therefore, I don't think that this function has any
place in a base MinGW distribution.
POSIX threads support for MS-Windows is provided by the pthreads-win32
project. Maybe they already provide a strtok_r() implementation. If
so, then you could use it; if not, you might ask them to consider
adding it.
The problem is most easily solved by adding an strtok_r implementation to the project's sources:
char *strtok_r(char *str, const char *delim, char **save)
{
char *res, *last;
if( !save )
return strtok(str, delim);
if( !str && !(str = *save) )
return NULL;
last = str + strlen(str);
if( (*save = res = strtok(str, delim)) )
{
*save += strlen(res);
if( *save < last )
(*save)++;
else
*save = NULL;
}
return res;
}