2

次のコードがあります。これは tomcrypto のマニュアルのコードであり、MS VC++ 2008 EE では動作しません。何か助けはありますか?また、オブジェクトchar*による置換を依頼できますか?std::string

int main(void)
{
hash_state md;
unsigned char *in = "hello world", out[16];
/* setup the hash */
md5_init(&md);
/* add the message */
md5_process(&md, in, strlen(in));
/* get the hash in out[0..15] */
md5_done(&md, out);
return 0;
}

エラー:

\main.cpp(7) : error C2440: 'initializing' : cannot convert from 'const char [12]' to 'unsigned char *'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
.\main.cpp(11) : error C2664: 'strlen' : cannot convert parameter 1 from 'unsigned char *' to 'const char *'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast

編集: コードは次のようになります。

int main(void)
{
register_hash(&md5_desc);
hash_state md;
char* p = "hello wordl";
unsigned char *in = reinterpret_cast<unsigned char*>(p);
char* out[16];
/* setup the hash */
md5_init(&md);
/* add the message */
md5_process(&md, const_cast<char*>(in), strlen(in));
/* get the hash in out[0..15] */
md5_done(&md, out);
return 0;
}

エラー:

\main.cpp(21) : error C2440: 'const_cast' : cannot convert from 'unsigned char *' to 'char *'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
.\main.cpp(21) : error C2664: 'strlen' : cannot convert parameter 1 from 'unsigned char *' to 'const char *'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
.\main.cpp(23) : error C2664: 'md5_done' : cannot convert parameter 2 from 'char *[16]' to 'unsigned char *'
        Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast
4

4 に答える 4

4
unsigned char *in = "hello world"

これは C++ では正しくありません: "hello world"は文字列リテラルであり、型はconst char[12]です。C では typechar[12]ですが、consthere は重要ではありません。C++ では、文字列リテラルを に変換できる暗黙的な (ただし非推奨の) 変換があるためchar*です。

問題は、charunsigned charが異なるタイプであることです。char署名されていないかどうかは問題ではありません。3 つのchar型 ( charunsigned char、およびsigned char) はすべて別個のものであり、C++ では、これらの 3 つの型へのポインターをキャストなしで変換することはできません。

これは C で機能します。これは、C ではオブジェクトへのポインター型をキャストなしで他のオブジェクトへのポインター型に変換できるためです。C++ ではそうではありません。

C++ では、以下を使用する必要があります。

// use the implicit conversion to 'char*' to cast away constness:
char* p = "hello world";

// explicitly cast to 'unsigned char*'
unsigned char* in = reinterpret_cast<unsigned char*>(p);

文字列リテラルは変更できないため、constness の削除は通常は悪い考えですが、const-correct ではないレガシー ライブラリを扱う場合は必要になることがあります。

C++ では、すべてのオブジェクトを、、またはの配列として扱うことができるため、からchar*への変換は安全です。unsigned char*charunsigned charsigned char

于 2011-04-19T14:09:42.317 に答える
2

charsigned charまたはとは異なる型unsigned charです。文字列リテラルは常に型(const) char *です。(const) signed char *したがって、それらをまたはに割り当てることはできません(const) unsigned char *。これを修正するには、unsigned4 行目から を削除します。

md5_process()関数が引数として明示的に を受け取る場合unsigned char *は、その時点でキャストを実行する必要があります。

md5_process(&md, reinterpret_cast<unsigned char*>(in), strlen(in));

[他の人が言ったように、文字列リテラルを指しているので as を実際に定義する必要がありますが、それはここでは問題ではありません。in]const char *in

于 2011-04-19T14:00:26.943 に答える
1

もう一度試してみましょう:

int main(void)
{
register_hash(&md5_desc);
hash_state md;
const char* p = "hello wordl";
const unsigned char* in = reinterpret_cast<const unsigned char*>(p);
unsigned char out[16];
/* setup the hash */
md5_init(&md);
/* add the message */
md5_process(&md, in, strlen(p));
/* get the hash in out[0..15] */
md5_done(&md, out);
return 0;
}

これは機能しますか?

于 2011-04-19T14:44:22.823 に答える
0

これは、リテラル文字列が C++ では const であるのに対し、非 const ポインターで初期化するためです。

const char* in = "hello world";
char * out[16];

ただし、 md5_process が非 const を取ると問題が発生する可能性がありchar*ます。この場合、非 const にキャストする必要があります。

md5_process(&md, const_cast<char*>(in), strlen(in));
于 2011-04-19T13:59:54.993 に答える