我正在将现有(主要)跨平台应用程序移植到WinCE 4.2。该函数的当前入口点是
int main(int argc, char *argv[]){}
我想按原样保留此部分,并让WinCE入口点简单地调用它。我相信以下内容应该有效:
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
int argc = _tcslen(lpCmdLine);
char *argv = new char[argc];
wcstombs(argv,lpCmdLine,1024);
argc = main(argc,&argv);
delete [] argv;
return argc;
}
它编译,并且应该运行一次我弄清楚链接器为什么会抛出,但是它是对的吗?
答案 0 :(得分:5)
真正简单的方法是只更改项目的链接器入口点并使用main(...)函数。
打开项目属性对话框,然后转到“Linker-> Advancedd”并根据以下内容设置“入口点”值:
如果您的切入点是:
int main(int argc, char *argv[])
然后将入口点设置为mainACRTStartup
但是,如果您从以下开始:
int _tmain(int argc, TCHAR *argv[])
然后输入点为mainWCRTStartup
答案 1 :(得分:2)
您的一般想法是正确的,但是您转换lpCmdLine可能会导致一些问题。请考虑以下事项:
$> myprogam.exe -a shortargument -b -c -d“带有空格的长参数”
传递给你的main函数的参数将是这样的:
argc = 7;
argv = {
"myprogram.exe",
"-a",
"shortargument",
"-b",
"-c",
"-d",
"long argument with spaces"
};
WinMain会收到一个像这样的长字符串:
lpCmdLine = "-a shortargument -b -c -d "long argument with spaces"";
因此,如果您正在进行任何命令行选项解析,那么您可能会破坏它。最通用的方法是循环通过lpCmdLine将所有空格(当然在匹配引号之外)设置为空字符(即'\ 0'或简单地为0)并跟踪指向第一个有效字符的指针。空字符序列。
添加:如果我从wince开发的时候正确地回忆起来,我似乎记得有关lpCmdLine的一些内容,因为它与win32兼容,所以它总是空的。要获得命令行,我认为您必须使用GetCommandLine。
答案 2 :(得分:2)
谢谢你们的有用答案。我写了以下内容,它现在和我们需要的一样有效。只有我们的代码将调用此可执行文件,并且从不使用引号,尽管这不会太难添加。此外,如果参数之间有多个空格,它可能不会很好,但同样,我们不必担心其他人使用此程序,它只是出于学术目的。如果您认为有必要进行改进,请编辑此帖子,并在评论中证明其合理性。
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow ) {
assert(lpCmdLine != NULL);
int argc = 1, ret = 0;
std::vector<char*> args;
// Copy the entire array to a regular cstr
int cmdLineLen = _tcslen(lpCmdLine);
char *argv = new char[cmdLineLen];
wcstombs(argv,lpCmdLine,cmdLineLen);
args.push_back(&argv[0]);
// Replace spaces with nulls to effectively create array of cstr
for(int i=0; i<cmdLineLen; i++){
if(argv[i] == ' '){
argv[i] = '\0';
args.push_back(&argv[i+1]); // Keep track of the first char in each word
argc++;
}
}
// argv[argc] should be NULL.
args.push_back(NULL);
try{ // Run the program
ret = main(argc,&args[0]);
}
catch(...){
// TODO: Report error here. Commented code works OK for WinCE .NET
// delete argv;
// throw;
ret = -1;
}
delete argv;
return ret;
}
另外,对于那些感兴趣的人,在命令行运行它
>myprogam.exe -a shortargument -b -c
将以下内容放入lpCmdLine
"-a shortargument -b -c"
另外,我的第一个猜测是argv需要删除[]'d(因为我新的char []'d),但是当我这样做时,该程序有一个致命的错误。当我切换到上面时,它工作。这是否违反了新的&gt;删除/新[] - &gt;删除[]规则?
答案 3 :(得分:1)
不,这不起作用。
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
// argc: This is the number of arguments NOT the strlen
int argc = _tcslen(lpCmdLine);
// argv: Is an array of char* NOT an array of char.
char *argv = new char[argc];
wcstombs(argv,lpCmdLine,1024);
// The argument passed as argc is not valid here.
argc = main(argc,&argv);
delete argv;
// You are returning the result of main that is correct.
// But re-using argc like this is smelly. Declare a new
// variable and let the compiler optimise away the extra use
// the compiler is VERY good at that.
return argc;
}
行。不是WinCE的专家。 如果我这样做,我会使用std :: vector你可以修改工作
int WINAPI WinMain( HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPTSTR lpCmdLine,
int nCmdShow)
{
std::vector<char*> args;
// Split lpCmdLine by space.
// Remember to watch for quotes when splitting (From 'Kevin Loney')
// For each argument do
args.push_back(<SOMTHING>)
// The last argv[argc] should be NULL.
args.push_back(NULL);
int result;
try
{
// argc does not include the last NULL so do a -1
result = main(args.size()-1,&args[0]);
}
catch(...)
{
// If <SOMTHING> includes dynamically allocating memory
// Then you should delete it here.
throw; // Re-Throw the exception to get the same behavior.
}
return result;
}