Functioncall minilib testing

develop
Warmist 2011-07-17 12:00:29 +03:00
parent 6c75e8cd88
commit d0c2f3b9f5
3 changed files with 120 additions and 12 deletions

@ -2,14 +2,13 @@
#include <dfhack/Console.h> #include <dfhack/Console.h>
#include <dfhack/Export.h> #include <dfhack/Export.h>
#include <dfhack/PluginManager.h> #include <dfhack/PluginManager.h>
#include <dfhack/VersionInfo.h> #include <dfhack/Process.h>
#include <vector> #include <vector>
#include <string> #include <string>
#include <sstream>
#include "luamain.h" #include "luamain.h"
#include "lua_Console.h" #include "lua_Console.h"
#include "functioncall.h"
using std::vector; using std::vector;
using std::string; using std::string;
@ -20,8 +19,8 @@ static SDL::Mutex* mymutex=0;
DFhackCExport command_result dfusion (Core * c, vector <string> & parameters); DFhackCExport command_result dfusion (Core * c, vector <string> & parameters);
DFhackCExport command_result lua_run (Core * c, vector <string> & parameters); DFhackCExport command_result lua_run (Core * c, vector <string> & parameters);
typedef typedef
int __stdcall (*dfprint)(const char*, char, char,void *ptr) ; int (__thiscall *dfprint)(const char*, char, char,void *) ;
DFhackCExport const char * plugin_name ( void ) DFhackCExport const char * plugin_name ( void )
{ {
@ -81,15 +80,20 @@ DFhackCExport command_result plugin_onupdate ( Core * c )
DFhackCExport command_result lua_run (Core * c, vector <string> & parameters) DFhackCExport command_result lua_run (Core * c, vector <string> & parameters)
{ {
//testing part{
c->Suspend(); c->Suspend();
std::stringstream ss; FunctionCaller caller(c->p->getBase());
ss<<parameters[0]; std::vector <int> args;
long i; args.push_back((size_t)"Hello world");
ss>>i; args.push_back(4);
dfprint mprint=(dfprint)(0x27F030+i); args.push_back(4);
mprint("Hello world",1,4,0); args.push_back(0);
dfprint mprint=(dfprint)(0x27F030+c->p->getBase());
mprint("Hello world",4,4,0);
caller.CallFunction((0x27F030),FunctionCaller::THIS_CALL,args);
c->Resume(); c->Resume();
return CR_OK; return CR_OK;
//}end testing
Console &con=c->con; Console &con=c->con;
SDL_mutexP(mymutex); SDL_mutexP(mymutex);
lua::state s=lua::glua::Get(); lua::state s=lua::glua::Get();
@ -116,7 +120,7 @@ DFhackCExport command_result dfusion (Core * c, vector <string> & parameters)
{ {
Console &con=c->con; Console &con=c->con;
con.print("%x\n",c->vinfo->getBase()); con.print("%x\n",c->p->getBase());
SDL_mutexP(mymutex); SDL_mutexP(mymutex);
lua::state s=lua::glua::Get(); lua::state s=lua::glua::Get();

@ -0,0 +1,23 @@
#ifndef FUNCTIONCALL__H
#define FUNCTIONCALL__H
#include <vector>
using std::vector;
class FunctionCaller
{
public:
enum callconv
{
STD_CALL, //__stdcall - all in stack
FAST_CALL, //__fastcall - as much in registers as fits
THIS_CALL, //__thiscall - eax ptr to this, rest in stack
CDECL_CALL //__cdecl - same as stdcall but no stack realign
};
FunctionCaller(size_t base):base_(base){};
int CallFunction(size_t func_ptr,callconv conv,const vector<int> &arguments);
private:
size_t base_;
};
#endif //FUNCTIONCALL__H

@ -0,0 +1,81 @@
#include "functioncall.h"
#define __F_TDEF(CONV,CONV_,tag) typedef int(CONV_ *F_TYPE##CONV##tag)
#define __F_T(CONV,tag) F_TYPE##CONV##tag
#define __F_TYPEDEFS(CONV,CONV_) __F_TDEF(CONV,CONV_,1)(int);\
__F_TDEF(CONV,CONV_,2)(int,int);\
__F_TDEF(CONV,CONV_,3)(int,int,int);\
__F_TDEF(CONV,CONV_,4)(int,int,int,int);\
__F_TDEF(CONV,CONV_,5)(int,int,int,int,int);\
__F_TDEF(CONV,CONV_,6)(int,int,int,int,int,int);\
__F_TDEF(CONV,CONV_,7)(int,int,int,int,int,int,int)
#define __FCALL(CONV,CONV_) if(conv==CONV)\
{ \
if(count==1)\
ret= (reinterpret_cast<__F_T(CONV,1)>(f))\
(arguments[0]);\
else if(count==2)\
ret= (reinterpret_cast<__F_T(CONV,2)>(f))\
(arguments[0],arguments[1]);\
else if(count==3)\
ret= (reinterpret_cast<__F_T(CONV,3)>(f))\
(arguments[0],arguments[1],arguments[2]);\
else if(count==4)\
ret= (reinterpret_cast<__F_T(CONV,4)>(f))\
(arguments[0],arguments[1],arguments[2],arguments[3]);\
else if(count==5)\
ret= (reinterpret_cast<__F_T(CONV,5)>(f))\
(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4]);\
else if(count==6)\
ret= (reinterpret_cast<__F_T(CONV,6)>(f))\
(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5]);\
else if(count==7)\
ret= (reinterpret_cast<__F_T(CONV,7)>(f))\
(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6]);\
}
#define __FCALLEX(CONV,CONV_) if(conv==CONV)\
{ if(count==1) {__F_T(CONV,1) tmp_F=reinterpret_cast<__F_T(CONV,1)>(f); return tmp_F(arguments[0]);}\
else if(count==2){__F_T(CONV,2) tmp_F=reinterpret_cast<__F_T(CONV,2)>(f); return tmp_F(arguments[0],arguments[1]);}\
else if(count==3){__F_T(CONV,3) tmp_F=reinterpret_cast<__F_T(CONV,3)>(f); return tmp_F(arguments[0],arguments[1],arguments[2]);}\
else if(count==4){__F_T(CONV,4) tmp_F=reinterpret_cast<__F_T(CONV,4)>(f); return tmp_F(arguments[0],arguments[1],arguments[2],arguments[3]);}\
else if(count==5){__F_T(CONV,5) tmp_F=reinterpret_cast<__F_T(CONV,5)>(f); return tmp_F(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4]);}\
else if(count==6){__F_T(CONV,6) tmp_F=reinterpret_cast<__F_T(CONV,6)>(f); return tmp_F(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5]);}\
else if(count==7){__F_T(CONV,7) tmp_F=reinterpret_cast<__F_T(CONV,7)>(f); return tmp_F(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6]);}\
}
/*else if(count==8)\
ret= (reinterpret_cast<__F_T(CONV,8)>(f))\
(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6],arguments[7]);\
else if(count==9)\
ret= (reinterpret_cast<int (CONV_*)(int,int,int,int,int\
,int,int,int,int)>(f))\
(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6],arguments[7],arguments[8]);\
else if(count==10)\
ret= (reinterpret_cast<int (CONV_*)(int,int,int,int,int\
,int,int,int,int,int)>(f))\
(arguments[0],arguments[1],arguments[2],arguments[3],arguments[4],arguments[5],arguments[6],arguments[7],arguments[8],arguments[9]);}*/
int FunctionCaller::CallFunction(size_t func_ptr,callconv conv,const vector<int> &arguments)
{
//nasty nasty code...
int ret=0;
void* f= reinterpret_cast<void*>(func_ptr+base_);
size_t count=arguments.size();
if(count==0)
return (reinterpret_cast<int (*)()>(f))(); //does not matter how we call it...
__F_TYPEDEFS(STD_CALL,__stdcall);
__F_TYPEDEFS(FAST_CALL,__fastcall);
__F_TYPEDEFS(THIS_CALL,__thiscall);
__F_TYPEDEFS(CDECL_CALL,__cdecl);
__FCALLEX(STD_CALL,__stdcall);
__FCALLEX(FAST_CALL,__fastcall);
__FCALLEX(THIS_CALL,__thiscall);
__FCALLEX(CDECL_CALL,__cdecl);
return ret;
}
#undef __FCALL
#undef __FCALLEX