構造体の背後に隠されている関数アドレスを取得しようとしています。残念ながら、void*
基本的なC ++変換は機能しないため、C++ template
代わりに使用しました。
1.基本的なC++変換は、構造内の関数では機能しません。なぜですか?void*
void * lpfunction;
lpfunction = scanf; //OK
lpfunction = MessageBoxA; //OK
私は単純な構造を作りました:
struct FOO{
void PRINT(void){printf("bla bla bla");}
void SETA(int){} //nothing you can see
void SETB(int){} //nothing you can see
int GETA(void){} //nothing you can see
int GETB(void){} //nothing you can see
};
///////////////////////////////////////////
void *lpFunction = FOO::PRINT;
そしてコンパイルエラー:
error C2440: 'initializing' :
cannot convert from 'void (__thiscall FOO::*)(void)' to 'void *'
2.機能メンバーのアドレスを取得することは不可能ですか?
次に、関数メンバーをアドレスに変換できるテンプレート関数を作成しました。それでは組み立てで呼びます。次のようになります。
template <class F,void (F::*Function)()>
void * GetFunctionAddress() {
union ADDRESS
{
void (F::*func)();
void * lpdata;
}address_data;
address_data.func = Function;
return address_data.lpdata; //Address found!!!
}
そしてここにコードがあります:
int main()
{
void * address = GetFunctionAddress<FOO,&FOO::PRINT>();
FOO number;
number.PRINT(); //Template call
void * lpdata = &number;
__asm mov ecx, lpdata //Attach "number" structure address
__asm call address //Call FOO::PRINT with assembly using __thiscall
printf("Done.\n");
system("pause");
return 0;
}
しかし、それは非常に具体的だと思います。LOCK-KEYのように見え、引数タイプのセットごとに新しいテンプレートを作成する必要があります。
オリジナル(OK):
void PRINT(); //void FOO::PRINT();
少し変更します:
void PRINT(int); //void FOO::PRINT(int);
古いテンプレートコードですぐに、コンパイラは次のように表示します。
//void (F::*func)();
//address_data.func = Function;
error C2440: '=' : cannot convert from
'void (__thiscall FOO::*)(int)' to 'void (__thiscall FOO::*)(void)'
なんで?それらは単なるアドレスです。
69: address_data.func = Function;
00420328 mov dword ptr [ebp-4],offset @ILT+2940(FOO::PRINT) (00401b81)
..。
EDIT3:私はより良い解決策を知っています:
void(NUMBER::*address_PRINT)(void) = FOO::PRINT;
int(NUMBER::*address_GETA)(void) = FOO::GETA;
int(NUMBER::*address_GETB)(void) = FOO::GETB;
void(NUMBER::*address_SETA)(int) = FOO::SETA;
void(NUMBER::*address_SETA)(int) = FOO::SETB;
テンプレートよりもはるかに優れています。ちなみに私は目標を達成したいです:
<special_definition> lpfunction;
lpfunction = FOO::PRINT; //OK
lpfunction = FOO::GETA; //OK
lpfunction = FOO::GETB; //OK
lpfunction = FOO::SETA; //OK
lpfunction = FOO::SETB; //OK
これは可能ですか?