创建一个可以运行的DLL [英] Create a DLL that can be run

查看:23
本文介绍了创建一个可以运行的DLL的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

假设我有一段代码可以打印Hello World!"到控制台.是否可以用 C++(最好是 Visual C++)编写一个可以使用 rundll32.exe 执行并运行此代码的库?如果是这样,如何?

解决方案

谷歌搜索rundll32",第三次点击是文档链接,

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

根据该文档,rundll32 调用用户指定的函数,其签名类似于 wWinMain(除了这里的第一个参数是窗口句柄而不是实例句柄),

void 回调入口点(HWND hwnd,HINSTANCE hinst,LPSTR lpszCmdLine,int nCmdShow);

所以,试试这个:

//文件 [foo.def]出口问好

//文件 [foo.cpp]#include 命名空间 myCode {无效sayHello(){使用命名空间标准;cout<<你好,世界!"<<结束;}}//命名空间 myCode#undef UNICODE#define UNICODE#include 外部C"__declspec( dllexport )无效回调 sayHello( HWND, HINSTANCE, wchar_t const*, int ){AllocConsole();freopen( "CONIN$", "r", stdin );freopen( "CONOUT$", "w", 标准输出);freopen( "CONOUT$", "w", stderr );DWORD const infoBoxOptions = MB_ICONINFORMATION |MB_SETFOREGROUND;MessageBox( 0, L"调用前...", L"DLL 消息:", infoBoxOptions );myCode::sayHello();MessageBox( 0, L"调用后...", L"DLL 消息:", infoBoxOptions );}

建筑&运行:

<前>[d:\开发\测试]> cl foo.cpp foo.def user32.lib/MD/LD/D _CRT_SECURE_NO_WARNINGS文件创建库 foo.lib 和对象 foo.exp[d:\开发\测试]> rundll32 foo.dll,sayHello[d:\开发\测试]> _

输出显示在它自己的控制台窗口中,通过 AllocConsole 创建,这通常是必需的,因为 rundll32 是一个 GUI 子系统程序(这也是 freopen 电话).

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

Windows has an utility called rundll32.exe that can execute native dynamic link libraries as applications.

Say I have a piece of code that prints "Hello World!" to the console. Is it possible to write a library in C++ (preferably Visual C++) that can be executed using rundll32.exe and will run this code? If so, how?

解决方案

Googling "rundll32", the 3rd hit was a link to documentation,

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

According to that documentation, rundll32 calls a user-specified function with signature like wWinMain (except the first argument here is a window handle instead of an instance handle),

void CALLBACK
EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);

So, trying this out:

// 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 );
}

Building & running:

[d:\dev\test]
> cl foo.cpp foo.def user32.lib /MD /LD /D _CRT_SECURE_NO_WARNINGS
foo.cpp
   Creating library foo.lib and object foo.exp

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

[d:\dev\test]
> _

The output is presented in its own console window, created via AllocConsole, which is generally necessary since rundll32 is a GUI subsystem program (this is also the reason for the freopen calls).

To present the output in an existing console window one can just omit the calls to AllocConsole and freopen, and redirect standard output of rundll32 to a pipe. E.g. standard output can be piped through Windows’ more when the output is just a few lines, or through some *nix-utility cat for more lines. However, in the standard command interpreter [cmd.exe] it doesn’t work to just redirect the output to con.

这篇关于创建一个可以运行的DLL的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆