2

既存の(ほとんど)クロスプラットフォームアプリケーションをWinCE4.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;
}

コンパイルされ、リンカーがスローされる理由がわかったら実行する必要がありますが、正しいですか?

4

4 に答える 4

5

これを行うための本当に簡単な方法は、プロジェクトのリンカーエントリポイントを変更し、main(...)関数を使用することです。

プロジェクトの[プロパティ]ダイアログを開き、[リンカー]-> [詳細]に移動して、以下に基づいて[エントリポイント]の値を設定します。

エントリポイントがこれである場合:

int main(int argc, char *argv[])

次に、エントリポイントをに設定しますmainACRTStartup

しかし、あなたが始めているなら:

int _tmain(int argc, TCHAR *argv[])

次に、エントリポイントはmainWCRTStartup

于 2010-10-19T15:40:32.603 に答える
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を使用する必要があると思います。

于 2009-01-12T07:37:59.770 に答える
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 を delete[] する必要がありました (新しい char[] を作成したため) が、これを実行すると、プログラムに致命的なエラーが発生しました。上記に切り替えると、うまくいきました。new->delete/new[]->delete[] ルールに違反していませんか?

于 2009-01-13T05:26:35.417 に答える
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;
}
于 2009-01-12T07:56:23.930 に答える