Link to home
Start Free TrialLog in
Avatar of suda4130
suda4130

asked on

UNICODE problem (error while compiling)

I am getting the following errors below when i select the character set as "Unicode".  It however works fine on a seperate project. I made sure that all the project properties were same but I am not sure how i am getting this error.

Is there a simple way to remove this error without having to remove the "unicode" option. ??

1>..\DXUT\Core\DXUT.cpp(797) : error C2664: 'DXUTParseCommandLine' : cannot convert parameter 1 from 'LPSTR' to 'WCHAR *'
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>..\DXUT\Core\DXUT.cpp(802) : error C2664: 'LoadLibraryA' : cannot convert parameter 1 from 'const wchar_t [11]' to 'LPCSTR'
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
1>..\DXUT\Core\DXUT.cpp(1117) : error C2664: 'GetModuleFileNameA' : cannot convert parameter 2 from 'WCHAR [260]' to 'LPCH'
1>        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
Avatar of LordOfPorts
LordOfPorts
Flag of United States of America image

Try clicking on Build on the menu and then Clean Solution followed by Rebuild Solution.

It appears that the switch to Unicode did not take effect since functions such as LoadLibraryA are called if the project is still ANSI.

If it does not work, at the top of StdAfx.h try adding the following lines:

#define UNICODE
#define _UNICODE

Lets look at the errors one at a time.

>> 'DXUTParseCommandLine' : cannot convert parameter 1 from 'LPSTR' to 'WCHAR *'

OK.  LPSTR is a typedef for

__nullterminated CONST CHAR*

where

CHAR

is a basic single byte char.

WCHAR* is fairly obvious: a wide character pointer, which is typedefed to

wchar_t

So, the compiler is moaning about the fact that you are passing a (single byte) char* to a function expecting a (double byte) wchar_t*.

The solution?  In your call to DXUTParseCommandLine() you will probably have something like

DXUTParseCommandLine ( "String here" );

Use the _T macro which results in the string contained being treated as a wide string if Unicode is defined, i.e.

DXUTParseCommandLine ( _T("String here") );

>> error C2664: 'LoadLibraryA' : cannot convert parameter 1 from 'const wchar_t [11]' to 'LPCSTR'

You are passing a UNICODE string to a function expecting an ANSI string.

As LordOfPorts was getting at, LoadLibraryA is the ANSI version of the LoadLibrary function.  You need to call the UNICODE version, LoadLibraryW.

However, the safer thing to do is use LoadLibrary(), which is not a function but in fact a define that evaluates to either LoadLibraryA or LoadLibraryW, depending on whether UNICODE is defined:

// WinBase.h

#ifdef UNICODE
#define LoadLibrary  LoadLibraryW
#else
#define LoadLibrary  LoadLibraryA
#endif // !UNICODE

>> 'GetModuleFileNameA' : cannot convert parameter 2 from 'WCHAR [260]' to 'LPCH'

You are passing a wide character array to a function expecting an ANSI character pointer.

typedef CHAR *PCHAR, *LPCH, *PCH;

So, LPCH is a pointer to a CHAR, where a CHAR is a normal char.

You need to pass a single byte char array.

Of course, you need to ensure that you have changed the project settings to UNICODE, and that the (what appears to be a) library DXUT supports UNICODE.

HTH
Avatar of suda4130
suda4130

ASKER

Thanks for the comments. I can fix it by append "W" to all the function names, But i have already changed the project properties to allow UNICODE. General=>Character Set=?Use Unicode Character Set. But it still does not pick up the UNICODE definitions and defaults to ANSI (e.g. LoadLibraryA instead of LoadLibraryW)
How should i solve this problem? What am i missing ?
suda4130, have you tried cleaning the solution (Build -> Clean Solution on the menu), adding

#define UNICODE
#define _UNICODE

at the top in StdAfx.h and rebuilding the solution (Build -> Rebuild Solution)?
I have tried adding the define at the top of StdAdx.h and it gives the same error
The define directives should suffice at least to instruct the compiler to translate LoadLibrary to LoadLibraryW, etc... Just to confirm you also cleaned the solution in order to get rid of any pre-compiled files and then used Build->Rebuild solution?

Can you post just the code lines in question that are mentioned in the error, i.e. 797, 802, and 1117 from DXUT.cpp?
I realize the problem is because i am trying to include code that is UNICODE into my solution that requires code that needs ASII and both these files call stdafx.h.

Is there a simple way to resolve this ?
All my source files need to include "stdafx.h" to compile.
Is there someway i can include UNICODE for some files and not for the rest ?
>> requires code that needs ASII
Not sure I understand that.  Does it really need ANSI, or is it just not using appropriate constructs, eg

CString t = "ANSI string";

CString t = _T("UNICODE if Unicode is defined, otherwise ANSI");

Where the _T macro makes the strings wide or single byte encoded if UNICODE is defined or not respectively.

If there is no clear need for the strings in the above example to be ANSI, wrap them with the _T macro.  But even so, please clarify why you think the code needs to be ANSI.
You are right. My code was initially built without the UNICODE.
So by putting #define UNICODE in stdafx.h, I get a lot of errors since they are ANSI

Error 17 error C2664: 'int CXListBox::GetTextWithColor(int,LPTSTR) const' : cannot convert parameter 2 from 'LPSTR' to 'LPTSTR' c:\dvl\cview\cview2007(lgr_cbr_dual_latest_working_3dtest)\xlistbox.cpp 135
Error 18 error C2664: 'CSize CDC::TabbedTextOutW(int,int,LPCTSTR,int,int,LPINT,int)' : cannot convert parameter 3 from 'char *' to 'LPCTSTR' c:\dvl\cview\cview2007(lgr_cbr_dual_latest_working_3dtest)\xlistbox.cpp 155
Error 19 error C2664: 'strlen' : cannot convert parameter 1 from 'LPTSTR' to 'const char *' c:\dvl\cview\cview2007(lgr_cbr_dual_latest_working_3dtest)\xlistbox.cpp 225
Error 20 error C2664: 'ATL::CStringT::FindOneOf' : cannot convert parameter 1 from 'const char [3]' to 'const wchar_t *' c:\dvl\cview\cview2007(lgr_cbr_dual_latest_working_3dtest)\xlistbox.cpp 369
Error 21 fatal error C1903: unable to recover from previous error(s); stopping compilation c:\dvl\cview\cview2007(lgr_cbr_dual_latest_working_3dtest)\xlistbox.cpp 369
Error 24 error C2664: 'XgPlot::XgSetYAxisTitle' : cannot convert parameter 1 from 'const char [9]' to 'LPCTSTR' c:\dvl\cview\cview2007(lgr_cbr_dual_latest_working_3dtest)\rftplotsdialog.cpp 117
........................

Is it possible to somehow have some source files(my DXUT files) compile with UNICODE and the rest of the source code compile without UNICODE (=>ANSII)

Or is it possible to static link to e a library that is UNICODE

It is very hard for me to make my entire application UNICODE aware since i have to go to all the functions and rewrite how they are defined.

Any advise ?

Thanks
SOLUTION
Avatar of mrwad99
mrwad99
Flag of United Kingdom of Great Britain and Northern Ireland image

Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I would advise against removing the UNICODE define directives if you plan to keep your project in Unicode mode and also against defining the directives only in certain files as you will most likely experience problems of comminication between various project components. Instead the better approach in my opinion would be to update the code so that you use generic data types and functions which will automatically be compiled to the proper version depending on if your project is Unicode or Multi-byte, e.g. use:

TCHAR (which becomes WCHAR if Unicode, CHAR otherwise)
LoadLibrary (which becomes LoadLibraryW if Unicode, LoadLibraryA otherwise)
LPCTSTR (which becomes LPCWSTR if Unicode, LPCSTR otherwise)
_tcslen (which becomes wcslen if Unicode, strlen otherwise)
Use the _T("") or TEXT("") macro to surround strings and they will be compiled to the wide characters or multi-byte automatically

This approach gives you the prower of generic programming and you can switch back and forth between Unicode and multi-byte. It is worth the effort of rewriting however if you would like to compile only the DUXT files in Unicode mode try switching your project back to multi-byte and remove the Unicode define directives from StdAfx.h, then at the top of the duxt.cpp define UNICODE and _UNICODE and at the end #undef both however you will most likely experience issues with this if the files exchange data with your main project.

Also the Windows data types definitions at http://msdn.microsoft.com/en-us/library/aa383751(VS.85).aspx might be helpful if you go for the generic approach.
LordOfPorts.

Thanks for the comments. By removing UNICODE from my stdafx.h (pch file), removes the errors from my code. But I still get errors using DXUT because it requires UNICODE definition in the stdafx file.

By putting #define UNICODE at the top of dxut.cpp file as you mentioned does not help. It needs UNICDE definition in the stdafx file. How do i overcome this issue ?

Just to confirm, if you place the following at the very top (above DXUT.h include) in the DXUT.cpp file:

#define UNICODE
#define _UNICODE

...and at the end of DXUT.cpp

#undef UNICODE
#undef _UNICODE

it does not make a difference? Do you still receive the same error as specified above?
>> It needs UNICDE definition in the stdafx file.

I cannot see how that can be the case.  Can you elaborate?
Here is the error iam getting when i include

//DXUT.cpp file

#define UNICODE
#define _UNICODE
#include "DXUT.h"
#define DXUT_MIN_WINDOW_SIZE_X 200
#define DXUT_MIN_WINDOW_SIZE_Y 200
#define DXUT_COUNTER_STAT_LENGTH 2048
....
#undef UNICODE
#undef _UNICODE

Error 3 fatal error C1010: unexpected end of file while looking for precompiled header. Did you forget to add '#include "stdafx.h"' to your source? c:\dvl\cview\cview2007(lgr_cbr_dual_latest_working_3dtest)\dxut.cpp 6148

So, it is asking me to include he pch file stdafx file. When i include the stdafx file that does not have #define UNICODE inside, I get the following errors

Error 1 error C2664: 'DXUTParseCommandLine' : cannot convert parameter 1 from 'LPSTR' to 'WCHAR *' c:\dvl\cview\cview2007(lgr_cbr_dual_latest_working_3dtest)\dxut.cpp 781
Error 2 error C2664: 'LoadLibraryA' : cannot convert parameter 1 from 'const wchar_t [11]' to 'LPCSTR' c:\dvl\cview\cview2007(lgr_cbr_dual_latest_working_3dtest)\dxut.cpp 786
Error 3 error C2664: 'GetModuleFileNameA' : cannot convert parameter 2 from 'WCHAR [260]' to 'LPCH' c:\dvl\cview\cview2007(lgr_cbr_dual_latest_working_3dtest)\dxut.cpp 1097
......
......
ASKER CERTIFIED SOLUTION
Link to home
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Start Free Trial
I agree.  There is not going to be a simple solution, and in the time that has been spent discussing this, you could have changed the problematic functions to use UNICODE equivalents.
Thanks for the suggestions.
Glad to help.