私には機能があります:
string f1 (unsigned char * value, int len)
{
...
}
変数を渡したいのですが
char buf[4096];
これを行うための最良の方法は何ですか?
私には機能があります:
string f1 (unsigned char * value, int len)
{
...
}
変数を渡したいのですが
char buf[4096];
これを行うための最良の方法は何ですか?
バッファの宣言を期待されるタイプに変更できますか?もしそうなら、私はお勧めします:
const unsigned int BUFFER_SIZE = 4096;
unsigned char buf[BUFFER_SIZE];
string result = f1(buf, BUFFER_SIZE);
その変数を制御できない場合は、
string result = f1(reinterpret_cast<unsigned char*>(buf), sizeof(buf)/sizeof(buf[0]));
len
バッファ内の要素の数を指していると思います(のドキュメントで調べてくださいf1
)。あなたはそれを得ることができます:
sizeof(buf) // as `sizeof(char)==1`
// or
sizeof(buf)/sizeof(buf[0]) // more commonly used, works with all types
これはここではとして機能しsizeof(char) == sizeof(unsigned char) == 1
ます。
もう一つのポイントは、あなたが呼び出すことができないということです
f1(buf, len);
「配列から4096文字」buf
である場合でも、暗黙的に「ポインタから文字」に変換できます。コンパイルオプションがない場合、Visual-C++はデフォルトで署名されます-> 。2つのタイプAとBの場合、C ++は、BがAの基本クラスである場合にのみ「ポインターからA」から「ポインターからB」への変換を実行します(§4.10conv.ptr)。これはとの場合には当てはまらないため、変換は暗黙的ではありません(標準の変換シーケンス、§4convではありません)。/J
char
signed char
unsigned char
signed char
reinterpret_cast
ただし、 :を使用して明示的にキャストすることはできます。
signed char as[4096];
int const len = sizeof(as)/sizeof(as[0]);
unsigned char* pu = reinterpret_cast < unsigned char* > (as);
f1(pu, len);
これは配列を渡すための最良の方法ですか?
微妙な点があります。関数が明示的にに特化されている場合、渡されたバッファunsigned char
の内容を「誤解」する可能性があります。signed char
さらに、f1
配列を変更すると、バッファを解釈するものが(の配列で機能したように)行ったsigned char
ことと競合する可能性があります。しかし、バッファが何を実行し、どのように解釈されるかを知っている場合は、このキャストを実行できます。f1
f1
unsigned char
f1
ポイントは何ですか?static_cast
ここで暗黙的または許可されていないのはなぜですか?(同じオブジェクト表現を持つ)へのポインタsigned
と型
の間の変換には特別な場合があるかもしれませんが、私はそれを見つけられませんでした。unsigned
基本的に、次のようなキャストは避けたいと考えています。
short s = 42;
long* pl = &s;
*pl = 4000; // possibly stack corruption
long l = 4200;
short* ps = &l;
*ps = 42;
//- value of l dependent e.g. on endianess
背景/標準
私はreinterpret_cast
実際に何をするかについて少し(またはそれ以上)興味があったので、ここでの残りは標準がそれについて何を言っているかについての詳細です。事実上、reinterpret_cast
は次のように解決されます(§5.2.10/ 7expr.reinterpret.cast):
unsigned char* pu = static_cast < unsigned char* > ( static_cast < void* > (as) );
詳細を見てみましょう。
内部static_cast < void* > (as)
:
static_cast
「配列からポインタ」への変換(§5.2.9/ 8expr.static.cast)と標準の変換シーケンス(§5.2.9/ 4、§4/ 3 convと比較)を実行できます。標準の変換シーケンスでは、「ポインタからA」から「ポインタからボイド」への変換が可能です。オペランドのメモリ位置の先頭を指すことが保証されています。配列は連続して割り当てられた要素のセットで構成されているため、これは問題ありません(§8.3.4dcl.array)。
外側static_cast < unsigned char* >
:これは、標準の変換の逆です。つまり、「ポインターから符号なし文字」から「ポインターからボイド」(§5.2.9/ 7 + 13)です。「pointertovoid」を介して「 pointertosignedchar」から「 pointertounsignedchar 」に変換するため、結果が何であるか(指定されていません)は定義されていません。char
とは異なるタイプであることに注意してくださいunsigned char
(§3.9.1/ 1basic.fundamental)。しかし、それはどんな正気のマシン/実装でも問題なく、同じオブジェクト表現signed char
を持っているはずです。unsigned char
驚くべきことf1((unsigned char*)buf, len);
に、トリックを行います。