300分请教高手dll的高级应用问题 一个程序,可以动态的加载动态连接库,写动态连接库的人可以给你一个文本来描述动态连接库的名 函数原型,注意是文本的,所以你的程序里不知道对方会给你一个什么样的函数、函数有几个参数,要求能够调用他的程序,假设参数是window标志的,没有用户自定义的类型。我已经实现了一半,就差函数参数的处理了谢谢 解决方案 » 免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货 你们没有过这样的需求吗?配置文件:“acc.dll”“int function1(int a, int b)”“a=5”“b=6”要求在你的程序里调用 我相信是可以实现的,因为com中的invoke就是这样调用的,vb和其他的解释语音也应该是这样的 够了;用LoadLibrary和GetProcAddress可以实现了 你把问题想的简单了,我传给你的时候是将函数和参数传给你了,但是是以串的形式传的,在你写程序的时候,根本不知道dll中函数的原型。 先GetProcAddress(),然后把参数 push 入栈,CALL 函数即可。 HMODULE hMod = LoadLibrary("***");void *proc = GetProcAddress(hMod, "***");*** Result;__asm{ push ***; push ***; push ***;...... mov eax, proc; call eax; mov Result, eax;} 是的,我也这么想,但是1 call方法不是c、c++的内置函数2 怎样push参数?就是这里不太明白,谢谢指教 __asm{这就表示用汇编语言,PUSH ,CALL都是汇编。至于用汇编实现循环,从书上引用一段就可以了,用不了多少时间。 我用你写的方法是可以实现,但是报错:#include "stdafx.h"#include <iostream>using namespace std;typedef void* (*pFunction)(...);int Func(int nParam1,int nParam2){ cout<<"yes :a"<< nParam1 <<" b "<< nParam2<<endl; return 3;}int _tmain(int argc, _TCHAR* argv[]){ pFunction pf = (pFunction)Func; int a=1,b=2; //void* c = (*pf)(a,b); int c; __asm { push a; push b; mov eax, pf; call eax; mov c, eax; } cout<< "c="<<c<<endl; return 0;}runt-time check failure# 0 the value of esp was not properly saved across a function call.我的msn:[email protected]欢迎指正。 NTDLL.DLL!77f97704() DllLoader.exe!_RTC_Failure(void * retaddr=0x004324ac, int errnum=0) + 0x2e C++ DllLoader.exe!_RTC_CheckEsp() + 0x19 C++> DllLoader.exe!main(int argc=1, char * * argv=0x00341678) 行40 + 0x10 C++ DllLoader.exe!mainCRTStartup() 行259 + 0x19 C KERNEL32.DLL!77e7ca90() 你的Func是 __cdecl 格式的。我举例的函数是__stdcall 格式。你调用FUNC需要自己清理栈。__asm { push b;//先B后A push a; mov eax, pf; call eax; mov c, eax; add esp,08h} CDECL 是由调用者负责清理栈的,所以要最后一句。别的方法,不知道。 everandforever(Forever) :你有msn吗?我们通过msn来交流好吗?谢谢 噢,我明白了,谢谢你。对于数组怎么处理,push的时候只写数组的地址(也就是数组名)就可以? 靜態鏈接不行嗎?你可以根據DLL文件獲得Lib導入庫要用到DumpBin.exe /exports xxx.dll>xxx.def 修改為常見的def 文件。再用lib .exe /def:xxx.def 生成xxx.lib .接下來就不用說了吧。 不行,我要写的是一个可以动态加载并运行指定dll的程序,但是我事先不知道dll中的函数原型,写dll的人要做的只是用文本将dll中要调用的函数类型告诉我就可以了。而我的程序不用有任何变化 force_eagle(战鹰) :能够再给的具体一点吗类的成员函数指针我知道 ->*但是如何用模板来包装?谢谢提供思路 不知道你说的是什么问题,我试了一下是可以传数组的。 这个是用来测试的DLL导出函数定义,__cdecl调用方式:__declspec(dllexport) void print(int* array,int size){ for(int i=0;i<size;i++) cout<<array[i]<<endl;}下面是调用代码:HMODULE hMod=LoadLibrary("dll.dll");PROC pfn=GetProcAddress(hMod,"print");int array[5]={1,2,3,4,5};int ** address=(int**)&array;__asm{ push 5; push address;//注意这里不能直接把数组名压到栈里,不知道你遇到的是不是这个问题 call pfn; add esp,8; //如果导出函数是__stdcall的,这个就不要了。}经测试一切正常。 webber84(***闭关修炼中***) :谢谢你,这不是我遇到的问题,我是想将参数放到数组,然后循环压栈,因为dll的函数中的参数个数可能是不同的类型,所以我要用一个variant 数组来存放收到到参数变量,然后压栈。不知道你是否明白了我的意思。 大家帮我网上面投一张票阿~~~ 如何判断系统当前有无菜单弹出, 甚至得到菜单句柄 在支持MFC的DLL程序中如何使用ActiveX?大问题了! 在线等待:单文档中画图的坐标问题 winsock包装在win32 dll中出现的问题,100分相送 问个小问题? 怎么让程序缩成windows右下角的任务栏上的图标? 如何从USB的缓存区中读取数据!//急 自绘CComboBox出错 tab键的问题,????? 高分求DNS查询源码 怎样得到winXP的API列表和详细解释(中英文皆可)。
“acc.dll”
“int function1(int a, int b)”
“a=5”
“b=6”
要求在你的程序里调用
用LoadLibrary和GetProcAddress可以实现了
在你写程序的时候,根本不知道dll中函数的原型。
void *proc = GetProcAddress(hMod, "***");
*** Result;
__asm
{
push ***;
push ***;
push ***;
......
mov eax, proc;
call eax;
mov Result, eax;
}
1 call方法不是c、c++的内置函数
2 怎样push参数?就是这里不太明白,谢谢指教
{
这就表示用汇编语言,PUSH ,CALL都是汇编。至于用汇编实现循环,从书上引用一段就可以了,用不了多少时间。
#include "stdafx.h"
#include <iostream>using namespace std;typedef void* (*pFunction)(...);int Func(int nParam1,int nParam2)
{
cout<<"yes :a"<< nParam1 <<" b "<< nParam2<<endl;
return 3;
}int _tmain(int argc, _TCHAR* argv[])
{ pFunction pf = (pFunction)Func;
int a=1,b=2; //void* c = (*pf)(a,b);
int c;
__asm
{
push a;
push b;
mov eax, pf;
call eax;
mov c, eax;
} cout<< "c="<<c<<endl;
return 0;
}
runt-time check failure# 0 the value of esp was not properly saved across a function call.
我的msn:[email protected]
欢迎指正。
DllLoader.exe!_RTC_Failure(void * retaddr=0x004324ac, int errnum=0) + 0x2e C++
DllLoader.exe!_RTC_CheckEsp() + 0x19 C++
> DllLoader.exe!main(int argc=1, char * * argv=0x00341678) 行40 + 0x10 C++
DllLoader.exe!mainCRTStartup() 行259 + 0x19 C
KERNEL32.DLL!77e7ca90()
你调用FUNC需要自己清理栈。
__asm {
push b;//先B后A
push a;
mov eax, pf;
call eax;
mov c, eax;
add esp,08h
}
对于数组怎么处理,push的时候只写数组的地址(也就是数组名)就可以?
你可以根據DLL文件獲得Lib導入庫
要用到DumpBin.exe /exports xxx.dll>xxx.def
修改為常見的def 文件。
再用lib .exe /def:xxx.def 生成xxx.lib .
接下來就不用說了吧。
但是如何用模板来包装?谢谢提供思路
__declspec(dllexport) void print(int* array,int size)
{
for(int i=0;i<size;i++)
cout<<array[i]<<endl;
}
下面是调用代码:
HMODULE hMod=LoadLibrary("dll.dll");
PROC pfn=GetProcAddress(hMod,"print");
int array[5]={1,2,3,4,5};
int ** address=(int**)&array;
__asm
{
push 5;
push address;//注意这里不能直接把数组名压到栈里,不知道你遇到的是不是这个问题
call pfn;
add esp,8; //如果导出函数是__stdcall的,这个就不要了。
}
经测试一切正常。
谢谢你,这不是我遇到的问题,我是想将参数放到数组,然后循环压栈,因为dll的函数中的参数个数可能是不同的类型,所以我要用一个variant 数组来存放收到到参数变量,然后压栈。不知道你是否明白了我的意思。