2

アプリケーションが新しいコンソール ウィンドウを生成することを決定/発生させる場所はどこですか (動的にリンクする場合)? 見落としている可能性のある定義またはプラグマ、またはデフォルトのランタイム dll の標準動作の変更はありますか? これらの質問が正しいかどうか確信が持てません。下の背景を読んで、ご容赦ください。正しい方向へのすべてのナッジを嬉しく思います。

背景: コンソール アプリケーション (/SUBSYSTEM:CONSOLE) は、起動時に新しいドーター コンソールを生成します。同じソースと構成セットアップを使用する他のアプリケーションはそうではありません。(一見) 唯一の違いは、提供されている 3rd-party-dll です。新しいサブコンソールのため、出力をリダイレクトできなくなりました (app.exe > dump.txt)。このアプリケーションではリダイレクトが不可欠です。

MS Visual Studio 2008 でその c/c++ コンソール アプリケーションを構築しています。このアプリケーションは、非常に乱雑な dll に動的にリンクしています。ライブラリ パック全体は、デバッグ情報なしのリリース ビルドとして 1 つのサード パーティによって提供されます。dll パックには、msvcr90.dll (9.0.30729.1) msvcp90.dll (9.0.30729.1) および msvcr80.dll (8.0.50727.42) が含まれています。

main() の stdout または stderr への最初の fprintf は、アプリケーションが開始されたシェルではなく、新しいコンソール ウィンドウに送られるため、これがどのような原因であっても非常にグローバルであるように思われます。

最初の試行では、Visual Studio 2005 (ライブラリ パッケージの最新バージョンまで使用していた) と 2010 (dll プロバイダーが推奨) でアプリケーションをビルドしました。これらのビルドはコンソールを生成しませんでしたが、別のバージョンのランタイムで割り当てられた可能性があるメモリが解放されたときにクラッシュしました。Dependency Walker を使用すると、dll がリンクされている「メイン」ランタイムを見つけることができました。

PS: 2 つの異なるランタイムに対する Afaik リンクは十分に危険です。ただし、71、80、90 ランタイム dll の r、c、および m バリアントを含む以前のバージョンの dll-pack よりも改善されています。

PPS: 以前は主に Linux で開発していたので、非常に基本的な間違いを犯していた可能性があります。無知であることを予めお詫び申し上げます。

更新 1:

Anton Kovalenko のアドバイスに従って、私はますます多くのライブラリを削除しました。次に、さらにコードを削除しました。最後に私は次のように締めくくった:

#include <stdio.h>
#include <Windows.h>

int main(int _argc, char **_argv)
{
printf("application running ...\n");
fflush(stdout);
Sleep(2000);
exit(0);
}

構成プロパティ > c/c++ > コマンド ライン:

/Od /Ob2 /D "_MBCS" /FD /EHsc /MD /Fo"a4input_interface_6.12_1.dir\Release\\" /Fd"a4input_interface_6.12_1.dir\Release\vc90.pdb" /W3 /nologo /c /TC /errorReport:prompt

[構成プロパティ] > [リンカー] > [コマンド ライン]:

/OUT:"D:\sascha\svn\a4_devel\cmakebuild\build\win32_release\inputinterfaces\.inter_612_1_32.exe" /VERSION:0.0 /INCREMENTAL:NO /NOLOGO /MANIFEST /MANIFESTFILE:"a4input_interface_6.12_1.dir\Release\.inter_612_1_32.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /SUBSYSTEM:CONSOLE /DYNAMICBASE:NO /ERRORREPORT:PROMPT kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib

構成プロパティ > マニフェスト ツール > コマンド ライン

/nologo /outputresource:"..\..\..\build\win32_release\inputinterfaces\.inter_612_1_32.exe;#1"

シェルが生成され、stdout を使用してリダイレクトできないという問題がまだあります (つまり、app.exe > test.txt)。したがって、「実行中のアプリケーション」というテキストは、exeが開始された同じシェルには出力されません。

私はまだ無知で、すべてのヒントに感謝しています.

更新 2:

コマンドライン用のバッチファイルを作成しました。それでコンパイルすると、exeは意図したとおりに動作します。

cl.exe /Od /Ob2 /D "_MBCS" /FD /EHsc /MD /Fo"a4input_interface_6.12_1.dir\Release\\" /Fd"a4input_interface_6.12_1.dir\Release\vc90.pdb" /W3 /nologo /c /TC /errorReport:prompt main.c

link.exe /OUT:"D:\sascha\svn\a4_devel\cmakebuild\build\win32_release\inputinterfaces\.inter_612_1_32.exe" /VERSION:0.0 /INCREMENTAL:NO /NOLOGO /MANIFEST /MANIFESTFILE:"a4input_interface_6.12_1.dir\Release\.inter_612_1_32.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /SUBSYSTEM:CONSOLE /DYNAMICBASE:NO /ERRORREPORT:PROMPT kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib a4input_interface_6.12_1.dir\Release\main.obj

mt.exe /manifest a4input_interface_6.12_1.dir\Release\.inter_612_1_32.exe.intermediate.manifest /nologo /outputresource:"D:\sascha\svn\a4_devel\cmakebuild\build\win32_release\inputinterfaces\.inter_612_1_32.exe";#1"

そのため、Visual Studio が提供するコマンド ラインに反映されていない機能があります。何を、なぜ?私はまだ無知で、すべてのヒントに感謝しています.

解決策: この名前の実行可能ファイル用に構成されたデバッガーがありました。それが私がこの振る舞いをした理由です:

  • inter_612_2_32.exe サブシェルなし
  • intes_612_2_32.exe サブシェルなし
  • inter_612_1_32.exe はサブシェルを生成します
  • intes_612_1_32.exe サブシェルなし

ProcessExplorer を使用すると、inter_612_1_32.exe が DbgHost.exe のサブプロセスであることがわかりました。残念ながら、私はそのリードに従わず、忘れてしまいました。

ロードされたDLLは実際には問題ではありませんでした。問題はレジストリの次のエントリでした: HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows NT\CurrentVersion\Image File Execution Options\inter_612_1_32.exe

このエントリは、DebugDiag、Application Verifier、またはその他のツールによって作成されたもので、ツールの GUI で削除しても削除されなかったと思います。

考えてくださった皆様、ありがとうございます。

4

1 に答える 1

1

サードパーティの dll の一部が と を呼び出している可能性がFreeConsoleありAllocConsole、説明した効果があります。DllMainfor内で実行すると、プロジェクトの依存関係である for ライブラリDLL_PROCESS_ATTACHに入る前に発生します。main()

ビルド環境に関連する別の説明はないようです。

インポート ライブラリにリンクするのではなく、LoadLibrary疑わしい dll に使用するプロジェクトを作成すると、より多くのことを学ぶことができます。FreeConsoleAllocConsoleDllMainLoadLibrary

于 2013-01-17T12:47:51.690 に答える