3

C ++が実際にコマンドライン引数をchar配列に変換するにはどうすればよいですか?これはどのような「秘密の」コードですか?これを行うコードはどこで表示できますか(アセンブリ内であっても、アセンブリを知っています)?それが助けになるなら、私はLinuxを使っています。

ありがとうございました

4

5 に答える 5

7

ほとんどの(すべて?)Unixベースのオペレーティングシステムでは、それらはすでにアレイです。これは、オペレーティングシステムがそこでプロセスを実行する方法です。プロセスが開始されると、すでに引数の配列が用意されています。

コマンドラインを配列に変換するコードは、シェル(bashなど)または別のプログラムを起動する他のプログラムに存在します。bash利用可能なソース、他のプログラムがあります—それは異なります。

Windowsでは、これらは1つの文字列(GetCommandLine()API呼び出しを使用して変更せずに取得できます)であり、言語仕様では配列として提供する必要があるため、Cランタイムライブラリによって解析されて配列に変換されます。

Visual C ++でコンパイルされたプログラムの場合、これを行うコードはVisualStudioディストリビューションに含まれています。インストールするには、インストーラーに「Cランタイムライブラリソースを含める」などのチェックボックスをオンにする必要がある場合があります。

于 2012-09-01T20:43:19.183 に答える
2

これは通常、プログラムのプロセスを作成するときにオペレーティングシステムによって処理されます。このコードは、Cで記述されている場合(たとえば、OSがCで記述されている場合)、またはアセンブリで記述されている場合があります。このためのコードを見つけるには、おそらくオペレーティングシステムのコードを調べる必要があります。

お役に立てれば!

于 2012-09-01T20:38:25.663 に答える
2

コマンドライン引数を管理し、プロセスの作成中にスタックに配置するのはOSの仕事です。

POSIXシステムの場合、実行パスは次のとおりです。

  1. プログラムでは、execle / execve / ...システムコールを呼び出し、新しいプロセスの実行可能ファイルとコマンドライン引数へのパスを渡します。
  2. このデータはカーネルに送られます
  3. カーネルは、新しいプロセスIDを考慮に入れるように内部構造を更新し、新しいプロセスにアドレス空間を割り当てます(また、カーネルは、古いアドレス空間が不要になった場合はそれを削除します)。カーネルはプロセスメモリをゼロで初期化し、古いメモリからスタックの最上位にある新しいアドレス空間に情報をコピーします。
  4. カーネルは新しいプロセスをスケジューリングキューに入れ、システムコールから戻り、exec()実行パスをユーザースペースに転送し、最終的にプロセスのエントリポイントに転送します(これは通常、crt0.oオブジェクトファイルからのルーチンであり、デフォルトですべての実行可能ファイルにリンクされています-このルーチンは)を呼び出しますmain()

Linuxの場合、次のコードを参照できます: http ://www.cs.fsu.edu/~baker/devices/lxr/http/source/linux/fs/exec.c#L383 :

383 /*
384  * 'copy_strings()' copies argument/environment strings from the old
385  * processes's memory to the new process's stack.  The call to get_user_pages()
386  * ensures the destination page is created and not swapped out.
387  */

userspace syscallの対応するdo_execve()カーネルではexecve()、1345行目でcopy_strings()'sが呼び出され、copy_strings()routineは実際にあなたが求めている仕事をします。

于 2012-09-01T21:31:44.703 に答える
1

これはcランタイムライブラリの一部です。それが何であるかを知りたい場合は、ここを見てください:Cランタイムライブラリとは何ですか?

Microsoft VisualStudioを使用して基本的なC++コンソールアプリを作成し、プログラムの最初の行にブレークポイントを設定しました。デバッグされると、プログラムはその行で停止し、呼び出しスタックを呼び出して、「main」を呼び出す関数を確認します。呼び出し元の関数はcランタイムの一部であり、これにはコマンドラインを操作するコードが含まれているようです...詳しくは説明していませんが、ここから始める必要があります。

于 2012-09-01T20:37:31.197 に答える
1

main()最初に実行されるのは実際のものではない場合があります。たとえば、Visual Studioでは、mainCRTStartup()Windows APIを呼び出してコマンドラインを取得および解析するエントリポイントとして機能する関数です(これは、デバッガーを使用している場合に表示されます)。

于 2012-09-01T20:38:39.510 に答える