例如编了以下一个dll
--------------- d1.dll ---------------
extern "C" _declspec(dllexport) int Max(int a, int b);
BOOL APIENTRY DllMain( HANDLE hModule, 
                       DWORD  ul_reason_for_call, 
                       LPVOID lpReserved
 )
{
    return TRUE;
}int Max(int a, int b)
{
if(a>=b)return a;
else
return b;
}-----------------------------------我打入 rundll32 d1.dll Max(5,8)
显示miss entry:Max(5,8)打入 rundll32 d1.dll Max 5 8 又没有反应!
懒得再编个调用他的exe,如何简单的测试dll?

解决方案 »

  1.   

    dl.dll 中必须包含一个 申明如下的入口函数
    extern "C" __declspec(dllexport) void  __cdecl MyEntryPoint(
      HWND hwnd,        // handle to owner window
      HINSTANCE hinst,  // instance handle for the DLL
      LPTSTR lpCmdLine, // string the DLL will parse
      int nCmdShow      // show state
    )调用时这样调用
    Rundll  dl.dll, MyEntryPoint   parameters...
      

  2.   

    应该是
    Rundll32  dl.dll, MyEntryPoint   parameters...
      

  3.   

    还是没太明白:
    是把Max改成下面这样吗?extern "C" __declspec(dllexport) void  __cdecl Max(
      HWND hwnd,        // handle to owner window
      HINSTANCE hinst,  // instance handle for the DLL
      LPTSTR lpCmdLine, // string the DLL will parse
      int nCmdShow      // show state
    )
    {
    .........
    }如果是这样,我的a b 怎么往里传?完整测试:
    ------------------------------------------------------
    #include "stdafx.h"
    #include "stdio.h"
    extern "C" __declspec(dllexport) int __cdecl Max(HWND hwnd,HINSTANCE hinst,LPTSTR lpCmdLine,int nCmdShow);BOOL APIENTRY DllMain( HANDLE hModule, 
                           DWORD  ul_reason_for_call, 
                           LPVOID lpReserved
     )
    {
        return TRUE;
    }extern "C" __declspec(dllexport) int __cdecl Max(HWND hwnd,HINSTANCE hinst,LPTSTR lpCmdLine,int nCmdShow)
    {
    /*
    if(a>=b)return a;
    else
    return b;*/
    printf("%s",lpCmdLine);
    return 42;
    }------------------------------
    执行 rundll32 t1.dll,Max 6 没有错误,但也没什么输出??
    我自己编了一个exe测试这些dll都是可以正常输出东西的?
    我都快要放弃rundll32了,还有什么 简单测试 dll的工具吗?
      

  4.   

    还是没太明白:
    是把Max改成下面这样吗?extern "C" __declspec(dllexport) void  __cdecl Max(
      HWND hwnd,        // handle to owner window
      HINSTANCE hinst,  // instance handle for the DLL
      LPTSTR lpCmdLine, // string the DLL will parse
      int nCmdShow      // show state
    )
    {
    .........
    }如果是这样,我的a b 怎么往里传?完整测试:
    ------------------------------------------------------
    #include "stdafx.h"
    #include "stdio.h"
    extern "C" __declspec(dllexport) int __cdecl Max(HWND hwnd,HINSTANCE hinst,LPTSTR lpCmdLine,int nCmdShow);BOOL APIENTRY DllMain( HANDLE hModule, 
                           DWORD  ul_reason_for_call, 
                           LPVOID lpReserved
     )
    {
        return TRUE;
    }extern "C" __declspec(dllexport) int __cdecl Max(HWND hwnd,HINSTANCE hinst,LPTSTR lpCmdLine,int nCmdShow)
    {
    /*
    if(a>=b)return a;
    else
    return b;*/
    printf("%s",lpCmdLine);
    return 42;
    }------------------------------
    执行 rundll32 t1.dll,Max 6 没有错误,但也没什么输出??
    我自己编了一个exe测试这些dll都是可以正常输出东西的?
    我都快要放弃rundll32了,还有什么 简单测试 dll的工具吗?
      

  5.   

    RunDll32 的使用方法与实现原理    RunDll32.exe是Windows系统自带的一个直接执行DLL中导出函数的小工具,使用方式上与16位系统的RunDll.exe兼容,但提供32位的支持。  RUNDLL32.EXE <dllname>,<entrypoint> <optional arguments>    首先指定函数所在DLL名称,然后是函数入口名称,最后是可选的参数。RunDll32.exe会使用标准的DLL搜索策略定位DLL,但最好是指定完整路径名,避免名称冲突。此外需要注意的是,DLL名称和函数入口名称之间的逗号必须要有,因为程序在解析命令行时是依靠此标识分隔字符串的。
        具体的使用方法可以参考微软知识库提供的文档    INFO: Windows Rundll and Rundll32 Interface    使用这个工具可以完成很多令人意想不到的管理功能,例如在脚本中退出Windows以及调用控制面板等更多控制功能等。
      
        RUNDLL and RUNDLL32
        Using Rundll    因为RunDll32实际上是提供了一个调用任意DLL函数的代理,所以只要此函数以名字导出,并且遵循一定的函数签名(Function Signature),就可以很方便的通过RunDll32调用。    void CALLBACK EntryPoint(HWND hwnd, HINSTANCE hinst, LPSTR lpszCmdLine, int nCmdShow);    而实际上RunDll32也可以应用在不符合此函数签名的函数上,例如前面提到的关闭Windows功能,调用的    BOOL ExitWindowsEx(UINT uFlags, DWORD dwReason);    虽然ExitWindowsEx的函数签名与RunDll32要求的不符,但实际上也可以使用,因为他在堆栈使用上可以利用RunDll32传入的参数。传入的hwnd被当成uFlags使用;hInst被当成dwReason使用。因为这两个值都是系统相关伪随机的,因此这样调用的效果伪随机(依赖窗口和模块句柄的分配算法)。这也是为什么使用此函数时往往要敲多次以尝试成功。
        详细的分析文章可以参考这个讨论What can go wrong when you mismatch the calling convention?     在了解了RunDll32.exe的使用方法后,我们来看看其实现原理。其源代码可以在Win2K源码包的win2k\private\windows\shell\rundll32目录下找到。    整个实现代码很简单,大概分为三个部分:ModuleEntry和WinMain前半部分完成初始化和其它薄记工作;ParseCommand完成命令解析、DLL载入以及函数入口获得,是核心部分;InitStubWindow和WinMain后半部分完成函数调用所需窗口句柄的初始化以及实际函数调用。    ParseCommand函数首先对命令行字符串进行分解,验证传入Dll名称是否指向有效的PE映像文件,并尝试载入DLL。
        在定义了WX86符号的Alpha系统上,需要使用wx86.dll导出的Wx86LoadX86Dll函数完成实际的DLL载入,并使用Wx86ThunkProc函数构造一个Thunk块,包装实际函数的调用。
        如果定义了WINNT符号的系统,还需要从DLL中获得DOS头的和载入配置信息中的版本信息,更新PEB的相关字段模拟相应Windows版本。
        在获取函数入口地址时,RunDll32会尝试获得相应后缀为W和A的函数名入口地址。因为Win32API中凡是使用了字符串的函数一般都提供了Unicode/Ansi两个版本。这样就可以避免要求用户在命令行强行指定,RunDll32也会字段转换命令行为对应形式的字符串,传递给目标函数。
        最后的调用很简单,依次传入Stub窗口句柄、模块句柄、命令行和显示属性,并用一个try...except保护起来,处理所有的(EXCEPTION_EXECUTE_HANDLER)异常情况,弹出异常信息对话框。
      

  6.   

    参考以下资料:
    http://www.blogcn.com/user8/flier_lu/main.asp?id=1190096
      

  7.   

    打入 rundll32 d1.dll Max 5 8 又没有反应!
    懒得再编个调用他的exe,如何简单的测试dll?
    =========================
    楼主,我想你搞错了吧.
    rundll32好像没法返回值的啊.没反应就是调用成功了啊.
    你在dll的函数里加入一条MessageBox(...)试试,肯定能跳出来.