深入浅出Dll(介绍函数导出、类导出、钓子dll、不同语言混合编程方法、插件等的实现方法)[1]

[入库:2005年8月19日] [更新:2007年3月24日]

本文简介:选择自 iceezone 的 blog

深入浅出dll(介绍函数导出、类导出、钓子dll、不同语言混合编程方法、插件等的实现方法)

所有代码均经过测试,如有问题可留言
一。简单的dll函数调用有两种方式:
     1。显式调用2。隐式调用.如下例子

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// dlltest.cpp : dll 撰写
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
#include <windows.h>
#include <stdio.h>

extern "c" __declspec(dllexport) int add(int n1, int n2);
bool apientry dllmain( handle hmodule, dword  ul_reason_for_call, lpvoid lpreserved)
{
if(ul_reason_for_call==dll_process_attach)
{
//trace0("dll initializing!\n");
}
else if(ul_reason_for_call=dll_process_detach)
{
//trace0("dll terminating!\n");
}
    return true;
}

__declspec(dllexport) add(int n1, int n2)
{
char sztxt[1024];
sprintf(sztxt,"%d + %d =%d",n1,n2,n1+n2);
messagebox(0,sztxt,"dll respond here:",0);
return 1;
}

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// usedll.cpp : dll 调用测试
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
#include <windows.h>

//#define usestatelib

// 隐式链接方式:
#ifdef usestatelib
  #pragma comment(lib,"lib\\dlltest.lib")
  extern "c" __declspec(dllimport) int add(int n1, int n2);
#endif

int apientry winmain(hinstance hinstance, hinstance hprevinstance, lpstr lpcmdline, int ncmdshow)
{
#ifndef usestatelib
// 显式调用方式:
    hinstance hins=loadlibrary("dlltest.dll");
if(!hins)
{
messagebox(0,"couldn't find dlltest.dll","error:",0);
return 0;
}
typedef int (dll_add)(int , int );
dll_add *testit=(dll_add*) getprocaddress(hins,"add");
if(testit)
{
(*testit)(1,2);
}else
{
messagebox(0,"couldn't find add from dlltest.dll","error:",0);
return 0;
}
freelibrary(getmodulehandle("dlltest.dll"));
#else
//隐式链接方式:
int nres= add(1, 2);
#endif
return 0;
}


//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
// 二。 导出类
// 注意ctest类应该定义在文件头,dllexport最好用宏作判断定义,
// 而这里仅作测试。
//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
1。dll生成:
// tdll.cpp : defines the entry point for the dll application.
//

#include "stdafx.h"

class __declspec(dllexport) ctest
{
private:
int m_nvalue;

public:
ctest() : m_nvalue(0) {}
int getvalue() const;
};
int ctest::getvalue() const
{
return m_nvalue;
}

bool apientry dllmain( handle hmodule,
                       dword  ul_reason_for_call,
                       lpvoid lpreserved
 )
{
    return true;
}

2。调用(记得把上述生成的tdll.dll及tdll.lib拷过来):
#pragma comment(lib, "tdll.lib")

class __declspec(dllimport) ctest
{
private:
int m_nvalue;

public:
ctest() : m_nvalue(1) {}
int getvalue() const;
};

int main(int argc, char* argv[])
{

ctest a;
int kk = a.getvalue();

return 0;
}
运行正确。

有趣的现象是:
    当我把应用端的dllimport错误的改成dllexport,程序依然可以build通过
   (不过注释了#pragma comment(lib, "tdll.lib")就不行),运行时结果
  是1(为区别于dll中初始值0,我把应用端的初始为1)。
    嗯,这是因为编译器在处理应用端的ctest时,编译确实看得见类结构,而链接时
  在tdll.lib中也可找getvalue()相应符号,所以build成功,运行时既然应用端自己
    的ctest是dllexport,当然就是直接运行它了。

//xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
//三。使用钓子的dll
//     1.参见我的qq本马程序:
// http://blog.gameres.com/thread.asp?blogid=386&;threadid=13701;threadid=13701
//     2.另一个用于按f3弹出dll框供输出debug信息的dll,代码如下:
// 用vc创建一个win32dll,并在菜单中选择insert下的resource,插入一个dialog按ctrl+s存盘,并编写内容如下:
// logdll.h内容:

本文关键:深入浅出Dll(介绍函数导出、类导出、钓子dll、不同语言混合编程方法、插件等的实现方法)
 

本站最佳浏览方式为 分辨率 1024x768 IE 6.0(或更高版本的 IE浏览器)

go top