Windowsには、ネイティブダイナミックリンクライブラリをアプリケーションとして実行できるrundll32.exeというユーティリティがあります。
「HelloWorld!」を出力するコードがあるとします。コンソールに。rundll32.exeを使用して実行でき、このコードを実行するライブラリをC ++(できればVisual C ++)で作成することは可能ですか?もしそうなら、どのように?
Windowsには、ネイティブダイナミックリンクライブラリをアプリケーションとして実行できるrundll32.exeというユーティリティがあります。
「HelloWorld!」を出力するコードがあるとします。コンソールに。rundll32.exeを使用して実行でき、このコードを実行するライブラリをC ++(できればVisual C ++)で作成することは可能ですか?もしそうなら、どのように?
「rundll32」をグーグルで検索すると、3 番目にヒットしたのはドキュメントへのリンクでした。
http://support.microsoft.com/kb/164787
そのドキュメントによると、次のrundll32
ような署名を持つユーザー指定の関数を呼び出しますwWinMain
(ただし、ここでの最初の引数はインスタンス ハンドルではなくウィンドウ ハンドルです)。
void CALLBACK
EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);
だから、これを試してみてください:
// File [foo.def]
EXPORTS
sayHello
// File [foo.cpp]
#include <iostream>
namespace myCode {
void sayHello()
{
using namespace std;
cout << "Hello, world!" << endl;
}
} // namespace myCode
#undef UNICODE
#define UNICODE
#include <windows.h>
extern "C"
__declspec( dllexport )
void CALLBACK sayHello( HWND, HINSTANCE, wchar_t const*, int )
{
AllocConsole();
freopen( "CONIN$", "r", stdin );
freopen( "CONOUT$", "w", stdout );
freopen( "CONOUT$", "w", stderr );
DWORD const infoBoxOptions = MB_ICONINFORMATION | MB_SETFOREGROUND;
MessageBox( 0, L"Before call...", L"DLL message:", infoBoxOptions );
myCode::sayHello();
MessageBox( 0, L"After call...", L"DLL message:", infoBoxOptions );
}
ビルドと実行:
[d:\開発\テスト] > cl foo.cpp foo.def user32.lib /MD /LD /D _CRT_SECURE_NO_WARNINGS foo.cpp ライブラリ foo.lib とオブジェクト foo.exp の作成 [d:\開発\テスト] > rundll32 foo.dll,sayHello [d:\開発\テスト] > _
出力は、 によって作成された独自のコンソール ウィンドウに表示されますAllocConsole
。これは通常、rundll32 が GUI サブシステム プログラムであるため必要です (これが呼び出しの理由でもありfreopen
ます)。
AllocConsole
出力を既存のコンソール ウィンドウに表示するには、との呼び出しを省略し、 の標準出力をパイプfreopen
にリダイレクトします。たとえば、標準出力は、出力がほんの数行rundll32
の場合は Windows を介してパイプでき、より多くの行の場合は *nix-utility を介してパイプできます。ただし、標準のコマンド インタープリタ [cmd.exe] では、単に出力を にリダイレクトするだけでは機能しません。more
cat
con
http://support.microsoft.com/kb/164787
このMSDNの記事はまだ正確だと思います。エントリポイントを次のように定義します
void CALLBACK EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);
rundll32 を使用して、適切に設計された関数を DLL で実行することは可能ですが、お勧めしません。そうすることは、DLL が rundll32 のプロセス設定 (大規模アドレス認識、ターミナル サービス認識、DPI 認識、昇格マニフェストなど) に翻弄されることを意味します。 heap)、それはあなたを含むすべての rundll32 プロセスに影響します。
別のEXEを書くだけです。
Joe とあなた自身が言ったように、次のようなものを使用します。
void CALLBACK func(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow)
{
std::cout << "Hello world!" << std::endl;
}
ただし、「func」がエクスポートされると、CALLBACK = __stdcall が _func@16 に変更されます。
この名前はhttp://support.microsoft.com/kb/140485に変更できます。
したがって、次のようなことを試してみてください。
rundll32.exe DLLTest.dll,_func@16