C++直接调用外部函数(一)

2014-11-24 12:32:27 · 作者: · 浏览: 2

#include "stdafx.h"

#include

#include

#include

#include

const int DC_STADCALL = 0, DC_CDECL = 1, DC_QWORD = 2, DC_NOWORD = 4, DC_RET_OBJ = 8, DC_RET_VAL = 16 + 8;

void *gObjectReturnPtr = NULL; // 没有用的

void callfn(void* 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:

}

}

class A {

public:

void show(char *msg)

{

printf("msg:%s/n", msg);

}

};

template

void* addressof(T t)

{

void *retValue;

__asm {

mov eax, t

mov retValue, eax

}

return retValue;

}

www.2cto.com

class DllModule;

class Function {

private:

void *addr;

int flags;

void *thisPtr;

union CalRet {

__int64 ll;

struct {

int lo;

int hi;

} i2;

char b8[8];

} ret;

public:

Function(void *func, int flag)

{

this->addr = func;

this->flags = flag;

this->thisPtr = NULL;

}

Function(HMODULE hmodule, const char *funcName, int flag)

{

this->addr = (void*)GetProcAddress(hmodule, funcName);

this->flags = flag;

this->thisPtr = NULL;

}

// Function(DllModule &dll, const char *funcName, int flag)

// {

// this->addr = dll.get(funcName);

// this->flags = flag;

// this->thisPtr = NULL;

// }

Function(void *func, void *thisPtr, int flag)

{

this->addr = func;

this->thisPtr = thisPtr;

this->flags = flag;

}

int operator()(int nargs, ...)

{

callfn(addr, &nargs, nargs, thisPtr, flags, ret.b8);

return ret.i2.lo;

}

};

class DllModule {

private:

HMODULE hmodule;

char dllName[128];

public:

DllModule(const char *name)

{

hmodule = LoadLibrary(name);

strncpy(dllName, name, 127);

printf("load library %s/n", name);

}

~DllModule()

{

FreeLibrary(hmodule);

printf("free library %s/n", dllName);

}

void* get(const char *name)

{

return GetProcAddress(hmodule, name);

}

Function cFunc(const char *name, void *thisPtr = NULL)

{

return Function(get(name), thisPtr, DC_CDECL);

}

Function winFunc(const char *name, void *thisPtr = NULL)

{

return Function(get(name), thisPtr, DC_STADCALL);

}

};

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

{

int ret;

DllModule cdll("msvcrt.dll");

ret = cdll.cFunc("printf")(2, "Hello, %s/n", "baby");

printf("ret %d/n", ret);

DllModule user32("user32.dll");

ret = user32.winFunc("MessageBoxW")(4, 0, L"Hello", L"OK", 0);

print