直接调用函数的函数
来源:互联网 发布:单片机控制电磁阀电路 编辑:程序博客网 时间:2024/04/30 07:15
调函数的一个通用函数。还没有看很明白,fn为函数地址,args为参数(func(int param, ...),直接传¶m就可以了),argc为参数个数,(32位机4字节为一个), optr为this指针(VC 的 __thiscall),flags为标志(下面有定义,__cdecl不用清堆栈,QWORD好像是返回8字节内容,其它的没有看明白,好像与GCC有关。buff是返回值保存的地方。从C++解释器underC源码中取出来的。这个用来调用DLL中的函数比较爽的,不用声明原型,直接调用。
typedef int (*CALLFN)();
const int DC_CDECL = 1, DC_QWORD = 2, DC_NOWORD = 4, DC_RET_OBJ = 8, DC_RET_VAL = 16 + 8;
void *gObjectReturnPtr = NULL;
void callfn(CALLFN fn, int args[], int argc, void *optr, int flags, void *buff)
{
int sz = sizeof(int)*argc;
__asm {
mov ecx, argc
mov ebx, args
// push the arguments onto the stack, backwards
a_loop:
cmp ecx,0
jz a_out
mov eax, [ebx + 4*ecx]
push eax
dec ecx
jmp a_loop
a_out:
mov ecx,optr // thiscall calling convention (MS only)
call fn
// Cleanup stack ptr if this was a cdecl call
mov ecx, flags
test ecx,DC_CDECL
jz a_over
add esp,sz
a_over:
test ecx,DC_RET_OBJ
jz a_again
// these cases are peculiar to GCC
cmp ecx,DC_RET_VAL
jl a_skip
mov ebx, gObjectReturnPtr
mov [ebx],eax
mov [ebx+4],edx
jmp a_finish
a_skip:
sub esp,4
a_again:
mov ebx,buff
test ecx,DC_QWORD
jnz a_dbl
mov dword ptr[ebx],eax
jmp a_finish
a_dbl:
fstp qword ptr[ebx]
a_finish:
}
}
__int64 addi8(__int64 i1, __int64 i2)
{
return i1 + i2;
}
__int64 call(const char *name, const char *func, int nargs, ...)
{
union CalRet {
__int64 ret;
char sret[8];
} ret;
HMODULE h;
h = LoadLibrary(name);
void *addr = (void*)GetProcAddress(h, func);
int flag = DC_CDECL;
void *optr = NULL;
char buff[8];
ret.ret = 0;
callfn(addr, (int*)&nargs, nargs, optr, flag, ret.sret);
printf("ret %I64d/n", ret.ret);
FreeLibrary(h);
return ret.ret;
}
__int64 call(void *func, int nargs, ...)
{
union CalRet {
__int64 ret;
char sret[8];
} ret;
int flag = DC_CDECL|DC_QWORD;
void *optr = NULL;
char buff[8];
ret.ret = 0;
callfn(func, (int*)&nargs, nargs, optr, flag, ret.sret);
printf("ret %I64u/n", ret.ret);
return ret.ret;
}
int main(int argc, char* argv[])
{
char *s = "Hello, %s, %d/n";
char *s1 = "GOGO";
int i = 32;
setlocale(LC_ALL, ".936");
call("msvcrt.dll", "wprintf", 2, L"Hello, %s/n", L"abc");
call(addi8, 4, (unsigned __int64)-1, 0I64);
return 0;
}
- 直接调用函数的函数
- Windows文件操作的直接函数调用
- 函数指针不能直接调用类的成员函数
- JavaScript:new 一个函数和直接调用函数的异同
- new 一个函数和直接调用函数的异同
- js new一个函数和直接调用函数的区别
- js中直接调用函数和new函数的区别
- Js new一个函数和直接调用函数的区别
- JavaScript--函数的直接调用和事件调用
- C++直接调用外部函数
- 直接调用普通函数地址
- Javascript - 定义函数直接调用
- 【#include<algorithm>】中包含的可以直接调用的函数
- 写自己的函数直接调用Linux system call
- 客户端通过 JSON直接调用服务器的函数。
- C/C++中调用直接用汇编写的函数
- Js New一个函数和直接调用的区别
- Js New一个函数和直接调用的区别
- 歌词
- 一个经典错误
- J2EE开发全程实录
- 买了个蓝牙耳机
- [转载]Linux 的 x86 汇编程序设计
- 直接调用函数的函数
- NetBIOS节点的类型
- 我爱捷波朗
- struts2 s:optiontransferselect 标签的使用
- 蓝牙耳机
- 【转载】VGA/QVGA到底是什么意思?
- 实现图片滚动的标签 html之marquee详解
- ssss
- Android的多线程限制