問題タブ [alloca]

For questions regarding programming in ECMAScript (JavaScript/JS) and its various dialects/implementations (excluding ActionScript). Note JavaScript is NOT the same as Java! Please include all relevant tags on your question; e.g., [node.js], [jquery], [json], [reactjs], [angular], [ember.js], [vue.js], [typescript], [svelte], etc.

0 投票する
1 に答える
48 参照

c++ - スタックに任意の一定サイズの構造体を割り当てる

私は小さな作業用プラグイン サーバーを作成しました。プラグインは共有オブジェクトを使用して実装されます。共有オブジェクトは実行時に(header ).soの呼び出しによって「サーバー」に手動でロードされます。dlopen<dlfcn.h>

すべての共有オブジェクト プラグインは同じインターフェースを持っています。

  • 基本的にdo_something、呼び出し元が解放すると予想されるヒープメモリへのポインタを返します。
  • idは単に ごとに一意の識別子.soです。
  • Tは、それぞれに固有の構造体.soです。戻り値の型が同じものもあれば、そうでないものもあります。ここでのポイントは、sizeof(T)具体.so的です。

.soサーバーは、バイナリのシンボルの動的な読み込みと読み取りを担当します。すべての.soプラグインは、サーバー バイナリで定義されたメソッドを介して相互に呼び出すことができますdo_something_proxy。これは、呼び出し元と呼び出し先の間の接着剤として機能します。

物事を少し単純化するために、プロキシが実行されたときに一連の呼び出しを使用して埋められsome_so_mapたプレーンであるとしましょう。std::unordered_map<size_t, so_handle_t>dlopen

私の問題は、すべての呼び出し元がコンパイル時にdo_something_proxy知っていることです。T前に述べたように、T呼び出しサイトごとに異なる場合があります。ただし、任意の呼び出しサイトでは変更されT ません。

参考までに、すべての呼び出し元が使用する定義を次に示します。

つまり、do_something_proxy任意のプラグインidは常に同じ戻り値の型を持ちます。

プロキシがない場合は、テンプレートdo_soemthing_proxy化して渡すTか、std::array<int8_t, N>with を使用するだけで、呼び出しがスタックに移動されたときにsizeof(T) == N割り当てられた不要なメモリがスライスされないようにすることができます。ただし、プロキシは、コンパイル時にすべての可能な戻り値の型を認識することはできず、無数のバージョンの をエクスポートします。Tdo_something_proxydo_something_proxy

だから私の質問はdo_soemthing_proxy、そのスタックに有効なサイズを割り当てる方法はありますかT(つまりalloca、スタック割り当ての他の形式を使用するか)?

私が知る限り、要求されたプラグインの関数から単一の値しか受け取ることができないため、allocaここでは機能していないようです。割り当てるサイズと、割り当てられたメモリにコピーするバイトの両方を同時に受け取ります。間に「押しつぶす」ことができれば...do_soemthing_proxydo_somethingdo_soemthing_proxyalloca

std::array<int8_t, N>の値に 256 または 1024 を使用して、スタックに一定量のメモリを割り当てることができることを知っていますN。ただし、このソリューションは少し汚れています。あるスタックフレームから別のスタックフレームにデータを不必要にコピーし、プラグインが返すことができるデータの量を制限します。さらに、(私はまだこのソリューションのベンチマークを行っていませんが) コンパイラが動的境界を越えてコピーを削除できない限り、1024 バイトをコピーすることは、つまりsizeof(std::string)バイトをコピーすることよりも多くの作業であると想定します。

理想的な世界では、do_soemthing_proxyこれを RAII で処理する構造体を返す必要があると思います。const std::any必要に応じて、スタック割り当てされた A。これは可能ですか?

これが c++ 内でまったく不可能な場合、スタックまたはベース ポインターを手動でハイジャックすることによって、アセンブリで移植可能な方法でこの動作を実現することは可能でしょうか?

ありがとう。