4

I was trying the sample code bagofwords_classification.cpp from openCV 2.4.5 to Visual Studio 2010 (VC++ based). But I found the error code :

error C2664: 'CreateDirectoryW' : cannot convert parameter 1 from 'const char *' to 'LPCWSTR'   

Can you help me to give me the solution about that problem? Thanks. :)

Update v1:

static void makeDir( const string& dir )
{
#if defined WIN32 || defined _WIN32
    CreateDirectory( dir.c_str(), 0 );
#else
    mkdir( dir.c_str(), S_IRWXU | S_IRWXG | S_IROTH | S_IXOTH );
#endif
}

static void makeUsedDirs( const string& rootPath )
{
    makeDir(rootPath + bowImageDescriptorsDir);
    makeDir(rootPath + svmsDir);
    makeDir(rootPath + plotsDir);
}
Dominikus Willy
  • 127
  • 3
  • 8

3 Answers3

5

CreateDirectory will be defined as CreateDirectoryW which expects its parameters to be "wide" strings (UTF-16 encoded WCHAR*).

To create a wide string you can prepend L to a regular string.

CreateDirectory(L"mydir", NULL);

Alternatively, you can switch your project to multibyte encoding in the properties. This will mean that calling CreateDirectory will automatically use the CreateDirectoryA version of the function which accepts char* strings. These are expected to be in the multibyte encoding of the active codepage.

user2093113
  • 3,230
  • 1
  • 14
  • 21
  • I must change CreateDirectory(...) into CreateDirectoryW(...), mustn't I? – Dominikus Willy May 15 '13 at 02:00
  • No, `CreateDirectoryW` is currently being called and that's where your problem lies. You are passing the wrong type of argument. You could explicitly call `CreateDirectoryA` which will allow you to pass a `char*`. However, if you intend to use a lot of Windows API functions with `char*` as opposed to `WCHAR*` you'd be better off changing the encoding of the project. – user2093113 May 15 '13 at 02:02
  • I don't have argument to be passed in. I am trying to learn the bagofwords_classification.cpp code and I will tell how to use that code if I execute that code successfully. – Dominikus Willy May 15 '13 at 02:10
5

You have code that calls CreateDirectory. When UNICODE is defined, that symbol is actually a macro for CreateDirectoryW; the intention is for you to use "ambiguous" function names when you're also using TCHAR instead of char or wchar_t, so you can switch between compiling for Unicode or Ansi programs.

However, std::string doesn't change according to UNICODE; it's always Ansi, so its c_str method always returns a char*, never wchar_t*. When you have a parameter that's always Ansi, you should explicitly call functions that are always Ansi, too. In this case, call CreateDirectoryA.

You could also consider using std::basic_string<TCHAR>, but that's probably heading in a direction you don't wish to go.

A quick fix would be to adjust your project settings so that UNICODE is no longer defined. Consult the documentation for your tool set to find out how to do that, or explore your IDE's project options.

Rob Kennedy
  • 161,384
  • 21
  • 275
  • 467
  • I use Visual Studio 2010 as my IDE. How can I do a quick fix? It seems as the good solution, but I still can't solve. – Dominikus Willy May 15 '13 at 07:40
  • I don't use Visual Studio, so you're at an advantage over me in being able to do as I suggested and explore the options available in the dialog. Searching Google yielded a question here on Stack Overflow, too: [How do I turn off Unicode in a VC++ project?](http://stackoverflow.com/questions/1319461/how-do-i-turn-off-unicode-in-a-vc-project) Sounds promising. – Rob Kennedy May 15 '13 at 11:16
3

CreateDirectoryW accepts wide char, if you are using Unicode mode it is ok. You probably should use CreateDirectory or CreateDirectoryA.

diwatu
  • 5,641
  • 5
  • 38
  • 61