If you try to change build type from Console (/SUBSYSTEM:CONSOLE)
to Windows (/SUBSYSTEM:WINDOWS)
, you'll get an error complaining that entry point WinMain is missing:
I think the best way to get around this would be to call your normal int main(int, char**)
from WinMain
:
#ifdef _WINDOWS_
INT WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
PSTR lpCmdLine, INT nCmdShow)
{
return main(0, NULL);
}
#endif
The problem is that ImageMagick is using the console parameters (and I plan to use them in future too):
So passing NULL
and 0
is probably not a good idea. How can I convert WinMain
arguments to main
arugments?
One way would be to use CommandLineToArgvW()
to parse the result of GetCommandLineW()
into an argv
-style array of UTF-16 encoded strings, then use WideCharToMultiByte()
to convert them to ANSI strings so you can then pass them to main()
(assuming you can't use wmain()
instead).
For example:
int w_argc = 0;
LPWSTR* w_argv = CommandLineToArgvW(GetCommandLineW(), &w_argc);
if (w_argv)
{
char** my_argv = new char*[w_argc];
int my_argc = 0;
for (int i = 0; i < w_argc; ++i)
{
int w_len = lstrlenW(w_argv[i]);
int len = WideCharToMultiByte(CP_ACP, 0, w_argv[i], w_len, NULL, 0, NULL, NULL);
my_argv[my_argc] = new char[len+1];
WideCharToMultiByte(CP_ACP, 0, wargv[i], w_len, my_argv[my_argc], len+1, NULL, NULL);
++my_argc;
}
main(my_argc, my_argv);
for (int i = 0; i < my_argc; ++i)
delete[] my_argv[i];
delete[] my_argv;
LocalFree(w_argv);
}
Alternatively:
int w_argc = 0;
LPWSTR* w_argv = CommandLineToArgvW(GetCommandLineW(), &w_argc);
if (w_argv)
{
std vector<std::string> my_argv_buf;
my_argv.reserve(w_argc);
for (int i = 0; i < w_argc; ++i)
{
int w_len = lstrlenW(w_argv[i]);
int len = WideCharToMultiByte(CP_ACP, 0, w_argv[i], w_len, NULL, 0, NULL, NULL);
std::string s;
s.resize(len);
WideCharToMultiByte(CP_ACP, 0, wargv[i], w_len, &s[0], len, NULL, NULL);
my_argv_buf.push_back(s);
}
std vector<char*> my_argv;
my_argv.reserve(my_argv_buf.size());
for (std vector<std::string>::iterator i = my_argv_buf.begin(); i != my_argv_buf.end(); ++i)
my_argv.push_back(i->c_str());
main(my_argv.size(), &my_argv[0]);
LocalFree(w_argv);
}
You can use CommandLineToArgvW
to parse and convert the command line into the format expected by "normal" C main-style functions.
int argc;
LPWSTR *argvw = CommandLineToArgvW(GetCommandLineW(), &argc);
CallCMainFunction(argvw, argc);
LocalFree(argvw);
Note that this is in wide characters, as windows natively expects utf-16 command line arguments. If InitializeMagick only operates with narrow chars, you'll have to convert those as well (which can be done with wcstombs_s
, with the caveats implied there
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With