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"

This is incorrect in C++: "hello world" is a string literal and is of type const char[12]. In C it is of type char[12], but the const here doesn't matter because in C++ there is an implicit (but deprecated) conversion that allows a string literal to be converted to a char*.

The problem is that char and unsigned char are different types. It doesn't matter whether char is unsigned; the three char types (char, unsigned char, and signed char) are all distinct and in C++ you cannot convert between pointers to those three types without a cast.

This works in C because in C you can convert any pointer-to-object type to any other pointer-to-object type without a cast. That isn't the case in C++.

In C++ you would need to use:

// 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);

The removal of constness is usually a bad idea since string literals are not modifiable, but sometimes it is necessary when dealing with legacy libraries that are not const-correct.

The conversion from char* to unsigned char* is safe because all objects can be treated as an array of char, unsigned char, or signed char in C++.

于 2011-04-19T14:09:42.317 回答
2

char is a different type to signed char or unsigned char; string literals are always of type (const) char *; so you cannot assign them to a (const) signed char * or a (const) unsigned char *. To fix this, remove the unsigned from line 4.

If your md5_process() function explicitly takes an unsigned char * as an argument, then you should perform a cast at that point:

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

[As others have said, you should really define in as const char *in as it's pointing to a string literal, but that is not the issue here.]

于 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

This is because litteral strings are const in C++, while you initialize it with a non-const pointer:

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

However it might cause a problem if md5_process takes a non-const char*, in this case you'll have to cast to a non-const:

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