创建一个可以运行的DLL

时间:2012-08-11 19:03:33

标签: c++ visual-c++

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

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

4 个答案:

答案 0 :(得分:8)

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

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
   Creating library foo.lib and object foo.exp

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

[d:\dev\test]
> _

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

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

答案 1 :(得分:3)

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

我认为这篇MSDN文章仍然准确;您将入口点定义为

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

答案 2 :(得分:2)

虽然可以使用rundll32在DLL中运行设计合理的函数,但不建议这样做。这样做意味着你的DLL受到rundll32的进程设置(大地址感知,终端服务感知,DPI感知,提升清单等)的支配。更糟糕的是:如果其他一些rundll32进程触发了应用程序兼容性行为(例如低碎片堆),这将影响包括你的所有rundll32进程。

只需写一个单独的EXE。

答案 3 :(得分:-1)

像乔和你自己所说,使用这样的东西:

 void CALLBACK func(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow) 
 { 
   std::cout << "Hello world!" << std::endl; 
 }

但是,CALLBACK = __stdcall,当你的“func”导出时会改为_func @ 16

您可以更改此名称http://support.microsoft.com/kb/140485

所以,你可能想尝试类似的东西:

rundll32.exe DLLTest.dll,_func@16