Windows有一个名为rundll32.exe的实用程序,可以将 native 动态链接库作为应用程序执行。

假设我有一段代码显示“Hello World!”。到控制台。是否可以用C++(最好是Visual C++)编写一个可以使用rundll32.exe执行并运行此代码的库?如果是这样,怎么办?

最佳答案

谷歌搜索“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:\dev\test]
> cl foo.cpp foo.def user32.lib/MD/LD/D _CRT_SECURE_NO_WARNINGS
foo.cpp
创建库foo.lib和对象foo.exp

[d:\dev\test]
> rundll32 foo.dll,说好

[d:\dev\test]
> _

输出显示在自己的控制台窗口中,该控制台窗口是通过AllocConsole创建的,由于rundll32是GUI子系统程序,因此通常是必需的(这也是freopen调用的原因)。

要在现有控制台窗口中显示输出,只需忽略对AllocConsolefreopen的调用,然后将rundll32的标准输出重定向到管道即可。例如。当输出只有几行时,标准输出可以通过Windows的more传递,或者通过* nix-utility cat传递更多的行。但是,在标准命令解释器[cmd.exe]中,仅将输出重定向到con是行不通的。

10-07 18:53