私は64時間目にバッファリングライブラリを作成しようとしています。かなり高度なものに取り掛かります。私はこれに関するいくつかのproffesional入力を求めるだろうと思った。関数ポインタをキャストする効果は何ですか?
typedef struct CharBuffer { char* address; } CharBuffer;
void (*CharBufferClear)(CharBuffer) = (void*) StdBufferClear;
は、この関数ポインタボイドを妨げる宣言するだろう:私はこれを持っている最初のヘッダファイルを#includes
別のヘッダファイルで
typedef struct StdBuffer { void* address; } StdBuffer;
extern void StdBufferClear(StdBuffer);
:私の最初のヘッダファイルで
私はこれを持っていますコール?彼らは価値の署名で一致しています。私は関数ポインタが以前は無効と宣言されたことはありませんでしたが、それをきれいにコンパイルする唯一の方法です。
Stackwiseこれはアセンブラコーディングで学んだこととはまったく異なるものではありません。
irrelevent OMG!私はちょうどStackOverflowでStackwiseを言った!
Hmm ..私はここであまりにも多くを仮定したように見えます。もし私が可能なら再確認することができます。私は、データの「タイプ」がそのアドレスに格納されているかどうかは気にしません。私が懸念しているのは、「ユニット」のサイズとそのアドレスにあるユニットの数です。 、あなたが見
typedef struct StdBuffer {
size_t width; ///< The number of bytes that complete a data unit.
size_t limit; ///< The maximum number of data units that can be allocated for this buffer.
void * address; ///< The memory address for this buffer.
size_t index; ///< The current unit position indicator.
size_t allocated; ///< The current number of allocated addressable units.
StdBufferFlags flags;///< The API contract for this buffer.
} StdBuffer;
をアドレスに、彼らが望むすべてが私は具体的でいただきました!memcpyを、MEMMOVEなどは本当に気にしない:あなたがする場合は、APIのインターフェース契約の契約を見てみましょう明らかにここを追跡しています。あなたはっきりデータ型はこのコンテキストでは関係ありません見たよう
typedef struct CharBuffer {
size_t width; ///< The number of bytes that complete a data unit.
size_t limit; ///< The maximum number of data units that can be allocated for this buffer.
char * address; ///< The memory address for this buffer.
size_t index; ///< The current unit position indicator.
size_t allocated; ///< The current number of allocated addressable units.
CharBufferFlags flags;///< The API contract for this buffer.
} CharBuffer;
:
は、この契約に従うことを最初のプロトタイプで、今見てください。場合によってはCが異なる方法で処理すると言うこともできますが、終わりにはaddress
は、
byte
は
byte
、
long
は
long
です。同じマシン上のメモリを扱っている限り。
このシステムの目的は、このタイプのすべてのジャグリングを削除することです。ジャグリングCはとても誇りに思っています(そして正当な理由で...)。私がしたいことはまさに無意味です。任意のアドレスにある標準サイズのデータ(1、2、4、8、sizeof(RandomStruct))のプロトタイプを作成します。
コードを使用して独自のキャストを実行し、特定の長さのメモリ単位でメモリの特定の長さのブロックで動作するAPI関数を使用してデータを操作できます。ただし、プロトタイプには公式のデータポインタ型が含まれている必要があります。エンドポインターで何か処理を行うたびに、エンドユーザーがデータを再作成する必要がないからです。ポインタが無効な場合、それをCharBufferと呼ぶのは意味がありません。
StdBuffer
は、すべての契約に準拠したデータ型を管理するために、API自体以外では決して使用されない汎用タイプです。
このシステムに組み込むapiは、私の最新のバッファリング版です。ここではっきりと文書化されています@Google Code私は、これをすべて一緒にするためにいくつかのことを変える必要があることを知っています。つまり、適切な研究や意見収集をしなくても、API内から直接データを操作する能力はありません。
StdBufferFlagsメンバーにSigned/Unsignedビットフラグが必要であることに注目したばかりです。
おそらく、このパズルの最後の部分はあなたの熟読のためです。
/** \def BIT(I)
\brief A macro for setting a single constant bit.
*
* This macro sets the bit indicated by I to enabled.
* \param I the (1-based) index of the desired bit to set.
*/
#define BIT(I) (1UL << (I - 1))
/** \enum StdBufferFlags
\brief Flags that may be applied to all StdBuffer structures.
* These flags determine the contract of operations between the caller
* and the StdBuffer API for working with data. Bits 1-4 are for the
* API control functions. All other bits are undefined/don't care bits.
*
* If your application would like to use the don't care bits, it would
* be smart not to use bits 5-8, as these may become used by the API
* in future revisions of the software.
*/
typedef enum StdBufferFlags {
BUFFER_MALLOCD = BIT(1), ///< The memory address specified by this buffer was allocated by an API
BUFFER_WRITEABLE = BIT(2), ///< Permission to modify buffer contents using the API
BUFFER_READABLE = BIT(3), ///< Permission to retrieve buffer contents using the API
BUFFER_MOVABLE = BIT(4) ///< Permission to resize or otherwise relocate buffer contents using the API
}StdBufferFlags;
ok最悪の場合のシナリオ:この '静的ライブラリ'のみの最適化を無効にします。その上の任意の入力? –
「最適化を無効にする」よりも細かい外科用器具があるかもしれません。例えば、GCCには厳密なエイリアシングに基づいて最適化を無効にするオプションがあります: '-fno-strict-aliasing'。 – Kaz
今どこかに行ってきました!まあ、少なくともそれはいいと思う。 –