程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> C++直接調用外部函數

C++直接調用外部函數

編輯:C++入門知識

 

#include "stdafx.h"

#include <stdarg.h>

#include <windows.h>

#include <locale.h>

#include <stdlib.h>

 

 

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<class T>

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);

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

    ret = cdll.cFunc("strstr")(2, "Caller has already cleaned the stack", "has");

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

    A a;

    ret = Function(addressof(A::show), &a, DC_STADCALL)(1, "Class function call");

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

    ret = user32.winFunc("FindWindowW")(2, NULL, L"Google - 谷歌浏覽器");

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

    srand(cdll.cFunc("time")(1, NULL));

    int r = rand();

    ret = user32.winFunc("ShowWindow")(2, ret, (r % 2) == 0);

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

    return 0;

}

摘自 lqefn的專欄
 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved