3

Windowsには、ネイティブダイナミックリンクライブラリをアプリケーションとして実行できるrundll32.exeというユーティリティがあります。

「HelloWorld!」を出力するコードがあるとします。コンソールに。rundll32.exeを使用して実行でき、このコードを実行するライブラリをC ++(できればVisual C ++)で作成することは可能ですか?もしそうなら、どのように?

4

4 に答える 4

10

「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] では、単に出力を にリダイレクトするだけでは機能しません。morecatcon

于 2012-08-11T19:41:48.307 に答える
3

http://support.microsoft.com/kb/164787

このMSDNの記事はまだ正確だと思います。エントリポイントを次のように定義します

  void CALLBACK EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);
于 2012-08-11T19:08:16.553 に答える
2

rundll32 を使用して、適切に設計された関数を DLL で実行することは可能ですが、お勧めしません。そうすることは、DLL が rundll32 のプロセス設定 (大規模アドレス認識、ターミナル サービス認識、DPI 認識、昇格マニフェストなど) に翻弄されることを意味します。 heap)、それはあなたを含むすべての rundll32 プロセスに影響します。

別のEXEを書くだけです。

于 2012-08-12T00:17:56.927 に答える
0

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 
于 2012-08-11T19:45:21.520 に答える