1

私には機能があります:

string f1 (unsigned char * value, int len)
{
...
}

変数を渡したいのですが

char buf[4096];

これを行うための最良の方法は何ですか?

4

3 に答える 3

1

バッファの宣言を期待されるタイプに変更できますか?もしそうなら、私はお勧めします:

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]));
于 2012-11-06T18:09:43.047 に答える
1

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ではありません)。/Jcharsigned charunsigned charsigned 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ことと競合する可能性があります。しかし、バッファが何を実行し、どのように解釈されるかを知っている場合は、このキャストを実行できます。f1f1unsigned charf1

ポイントは何ですか?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

于 2012-11-06T18:16:06.587 に答える
0

驚くべきことf1((unsigned char*)buf, len);に、トリックを行います。

于 2012-11-06T18:07:19.567 に答える