【解決方法】C++ システムコール経由で cl を実行する方法


ご挨拶とご挨拶
実行しようとしています cl.exe C++経由 system(...) 以下に示す引数を使用して呼び出します。

"C:/Program Files/Microsoft Visual Studio/2022/Preview/VC/Tools/MSVC/14.35.32019/bin/HostX64/x64/CL.exe" /JMC /permissive- /ifcOutput "x64/Debug" /GS /W3 /Zc:wchar_t /I"C:/Program Files (x86)/Visual Leak Detector/include" /ZI /Gm- /Od /sdl /Fd"x64/Debug/vc143.pdb" /Zc:inline /fp:precise /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MDd /std:c++20 /FC /Fa"x64/Debug/" /EHsc /nologo /Fo"x64/Debug/" /Fp"x64/Debug/IOWIU.pch" /diagnostics:column /c main.cpp

結果は、次のようにエラーになります。

calling : system("C:/Program Files/Microsoft Visual Studio/2022/Preview/VC/Tools/MSVC/14.35.32019/bin/HostX64/x64/CL.exe" /JMC /permissive- /ifcOutput "x64/Debug" /GS /W3 /Zc:wchar_t /I"C:/Program Files (x86)/Visual Leak Detector/include" /ZI /Gm- /Od /sdl /Fd"x64/Debug/vc143.pdb" /Zc:inline /fp:precise /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MDd /std:c++20 /FC /Fa"x64/Debug/" /EHsc /nologo /Fo"x64/Debug/" /Fp"x64/Debug/IOWIU.pch" /diagnostics:column /c main.cpp)
'C:/Program' is not recognized as an internal or external command,
operable program or batch file.
return value is : 1

コマンド ラインから同じ同じコマンドを実行すると、次に示すように正しく実行されます。

C:\Users\Bernard\source\repos\IOWIU>"C:/Program Files/Microsoft Visual Studio/2022/Preview/VC/Tools/MSVC/14.35.32019/bin/HostX64/x64/CL.exe" /JMC /permissive- /ifcOutput "x64/Debug" /GS /W3 /Zc:wchar_t /I"C:/Program Files (x86)/Visual Leak Detector/include" /ZI /Gm- /Od /sdl /Fd"x64/Debug/vc143.pdb" /Zc:inline /fp:precise /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MDd /std:c++20 /FC /Fa"x64/Debug/" /EHsc /nologo /Fo"x64/Debug/" /Fp"x64/Debug/IOWIU.pch" /diagnostics:column /c main.cpp
main.cpp
#include C:\Users\Bernard\source\repos\bpwSoftware\execution.MACROS.H

C:\Users\Bernard\source\repos\IOWIU>

以下は関連するコードです。

string cl_path = "C:/Program Files/Microsoft Visual Studio/2022/Preview/VC/Tools/MSVC/14.35.32019/bin/HostX64/x64/CL.exe";
string cl_options = "/JMC /permissive- /ifcOutput \"x64/Debug\" /GS /W3 /Zc:wchar_t /I\"C:/Program Files (x86)/Visual Leak Detector/include\" /ZI /Gm- /Od /sdl /Fd\"x64/Debug/vc143.pdb\" /Zc:inline /fp:precise /D \"_DEBUG\" /D \"_CONSOLE\" /D \"_UNICODE\" /D \"UNICODE\" /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MDd /std:c++20 /FC /Fa\"x64/Debug/\" /EHsc /nologo /Fo\"x64/Debug/\" /Fp\"x64/Debug/IOWIU.pch\" /diagnostics:column /c";

string sspace = " ";
string sdbl_quotes = "\"";
auto left_paren = '(';
auto right_paren = ')';
auto system_arg = sdbl_quotes + cl_path + sdbl_quotes + sspace + cl_options + sspace + "main.cpp";
cout << "calling : system" << left_paren << system_arg << right_paren << endl;
auto result = system(system_arg.c_str());
cout << "return value is : " << result << endl;

への呼びかけ system() オリジナル付き cl_path 次のようにエラーなしで動作します sdbl_quotes に事前事後保留されます cl_path 最初の 2 つのオプションのみが渡された場合、明らかに問題は 3 番目のオプション、つまり wit にある \"x64/Debug/\" それを渡すと最初の2つだけで残りのオプションはどれも通常のCMDエラーになりません

シェル
'C:/Program' is not recognized as an internal or external command,
operable program or batch file.

プロジェクトのプロパティ ページからコピーされた元のオプションは、引用符がオプション引数の一部であることに注意してください。 "x64\Debug\" 文字列型を形成するように私の変換されたフォーム: \"x64/Debug/\" 解決方法がわからないというエラーが発生します。

以下は、画面出力の直接コピー/貼り付けです。 への道はご覧の通り cl.exe これはまさにコマンド プロセッサが認識し、認識すべきものであり、それでも CMD エラーが発生します。 また、 /I オプション引数も引用されます。 次の出力で、前後の引用符に注意してください /I オプション引数が削除され、結果は CMD エラーではない 呼び出しの成功を示すと予想されるコンパイラ エラーのみが報告された cl.exe.

「ターミナル」
__cplusplus 199711 _MSVC_LANG 202002
SYSTEM 2022-12-04 03:41:32.3135127
UTC    2022-12-04 03:41:32.3230103
TAI    2022-12-04 03:42:09.3644184
GPS    2022-12-04 03:41:50.3716110
FILE   2022-12-04 03:41:32.3781440
LOCAL  2022-12-03 22:41:32.3945656

calling : system("C:/Program Files/Microsoft Visual Studio/2022/Preview/VC/Tools/MSVC/14.35.32019/bin/HostX64/x64/CL.exe" /permissive- /GS /W3 /Zc:wchar_t /I "C:\Users\Bernard\source\repos\bpwSoftware" /Gm- /Od /sdl /Zc:inline /fp:precise /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MDd /std:c++20 /FC /EHsc /nologo /diagnostics:column /D _DEBUG /D _CONSOLE /D _UNICODE /D UNICODE TEST.cpp)
'C:/Program' is not recognized as an internal or external command,
operable program or batch file.
return value is : 1

C:\Users\Bernard\source\repos\IOWIU\x64\Debug\IOWIU.exe (process 14484) exited with code 0.
Press any key to close this window . . .

「ターミナル」
__cplusplus 199711 _MSVC_LANG 202002
SYSTEM 2022-12-04 03:39:47.9385039
UTC    2022-12-04 03:39:47.9444312
TAI    2022-12-04 03:40:24.9793121
GPS    2022-12-04 03:40:05.9859770
FILE   2022-12-04 03:39:47.9899277
LOCAL  2022-12-03 22:39:48.0050586

calling : system("C:/Program Files/Microsoft Visual Studio/2022/Preview/VC/Tools/MSVC/14.35.32019/bin/HostX64/x64/CL.exe" /permissive- /GS /W3 /Zc:wchar_t /I C:\Users\Bernard\source\repos\bpwSoftware /Gm- /Od /sdl /Zc:inline /fp:precise /errorReport:prompt /WX- /Zc:forScope /RTC1 /Gd /MDd /std:c++20 /FC /EHsc /nologo /diagnostics:column /D _DEBUG /D _CONSOLE /D _UNICODE /D UNICODE TEST.cpp)
TEST.cpp
C:\Users\Bernard\source\repos\IOWIU\TEST.cpp(1,9): error C2065: 'z': undeclared identifier
return value is : 2

C:\Users\Bernard\source\repos\IOWIU\x64\Debug\IOWIU.exe (process 14728) exited with code 0.
Press any key to close this window . . .

結論として、問題はずっと引用符の欠如ではありませんでした cl.exe 上記の 2 つのウィンドウが明確に示しており、繰り返し述べられているように、パスはずっと存在していましたが、以前にも述べられ、上で明確に示されているように、オプションの引数に引用符が存在します。
不必要で面倒な繰り返しを避けるために、親切な読者/アドバイザー/ヘルパーが、アドバイス/支援/支援する前に、すべてのテキスト/コメントなどを読み/研究/理解する努力をすることをお勧めします.
さらにサポートが必要な場合は、 /I オプションは 5 番目、つまり 1 、 2 、 3 、 4 、 5 です。 ビンゴ! それはどれほど大変でしたか。 カウントはコンピュータ サイエンスのクラスで教えられていると思います。
よろしく

私が試したこと:

C++ system() に関するドキュメント、CMD エスケープ文字に関するドキュメント、スペースを含む長いパス名に関するドキュメントを参照してください。

解決策 1

問題は、おそらくパスを引用符で囲んでいないことです。 たとえば、よく見てください。

system("C:/Program Files/Microsoft Visual Studio/2022/Preview/VC/Tools/MSVC/14.35.32019/bin/HostX64/x64/CL.exe" ...");

する必要があります

system("\"C:/Program Files/Microsoft Visual Studio/2022/Preview/VC/Tools/MSVC/14.35.32019/bin/HostX64/x64/CL.exe\" ...");

引数を引用符で囲む必要があるすべてのコマンド ライン パラメーターについても同様です。 \” エスケープ シーケンスは、文字列リテラルに引用符を付けます。

解決策 2

これは、昨日あなたが抱えていた問題とほぼ同じです。 バックスラッシュまたはスペースを含むパスは、コマンド プロセッサがそれらを誤って解釈するのを防ぐために、特別に処理する必要があります。 最初の行を次のように変更する必要があります。

C++
string cl_path = "\"C:/Program Files/Microsoft Visual Studio/2022/Preview/VC/Tools/MSVC/14.35.32019/bin/HostX64/x64/CL.exe\"";

そうすれば、システム コールは引用符で囲まれた文字列をコマンド プロセッサに渡し、コマンド プロセッサはそれを完全なパスとして認識します。

コメント

タイトルとURLをコピーしました