私は次のようなことをすることができますか?
typedef void (*functor)(void* param);
//machine code of function
char functionBody[] = {
0xff,0x43,0xBC,0xC0,0xDE,....
}
//cast pointer to function
functor myFunc = (functor)functionBody;
//call to functor
myFunc(param);
私は次のようなことをすることができますか?
typedef void (*functor)(void* param);
//machine code of function
char functionBody[] = {
0xff,0x43,0xBC,0xC0,0xDE,....
}
//cast pointer to function
functor myFunc = (functor)functionBody;
//call to functor
myFunc(param);
正式には、C言語では関数ポインターとオブジェクトポインター間の変換が許可されていないため、これを行うことはできません。
ただし、多くのC実装(おそらく「ほとんど」)は、これを拡張機能としてサポートしています。それが機能するかどうかは、メモリのアクセス許可やキャッシュの一貫性などに依存します。これらは、アーキテクチャやオペレーティングシステムによって異なります。
保護リングによって異なります。
data segment
最も一般的なデスクトッププラットフォームでは、ページ権限のためにコードを実行できません。
最新のオペレーティングシステムでは、メモリが実行可能としてマークされているかどうかによって異なります。POSIXシステムでは、を使用して実行可能メモリを取得できる場合mmap
があります。特定のCPUアーキテクチャでも、呼び出し規約が異なる場合があることに注意してください。たとえば、呼び出し元が呼び出し先がスタックから引数をクリアすることを期待している場合、コードはそれを実行する方がよいでしょう。そうしないと、戻り時にクラッシュします。(通常、C ABIはこの愚かな要件を作成しませんが、それについて考える必要があります。)
マシンコードをC関数ポインターとして直接呼び出そうとするよりも、それを呼び出すインラインasmラッパーを作成する方がよい場合があります。このようにして、呼び出し規約を制御できます。
それはうまくいくかもしれません。多くのプラットフォームでは静的constストレージが読み取り専用プログラムメモリセクションに配置されるため、マシン命令にconstchar[]を使用する方がさらに優れている可能性があります。