C-код в C ++ компиляторе - PullRequest
       29

C-код в C ++ компиляторе

2 голосов
/ 19 апреля 2011

У меня есть следующий код, это код из руководства Томскрипто, и он не будет работать на 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 голосов
/ 19 апреля 2011
unsigned char *in = "hello world"

Это неверно в C ++: "hello world" является строковым литералом и имеет тип const char[12]. В C он имеет тип char[12], но const здесь не имеет значения, потому что в C ++ есть неявное (но не рекомендуемое) преобразование, которое позволяет преобразовать строковый литерал в char*.

Проблема в том, что char и unsigned char - это разные типы. Не имеет значения, является ли char неподписанным; три типа char (char, unsigned char и signed char) все различны, и в C ++ вы не можете преобразовывать указатели на эти три типа без приведения.

Это работает в 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);

Удаление константности обычно является плохой идеей, поскольку строковые литералы не могут быть изменены, но иногда это необходимо при работе с устаревшими библиотеками, которые не являются правильными.

Преобразование из char* в unsigned char* безопасно, поскольку все объекты могут обрабатываться как массив char, unsigned char или signed char в C ++.

2 голосов
/ 19 апреля 2011

char отличается от signed char или unsigned char; строковые литералы всегда имеют тип (const) char *; поэтому вы не можете присвоить их (const) signed char * или (const) unsigned char *. Чтобы это исправить, удалите unsigned из строки 4.

Если ваша md5_process() функция явно принимает unsigned char * в качестве аргумента, то вы должны выполнить приведение в этот момент:

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

[Как уже говорили другие, вы действительно должны определить in как const char *in, так как он указывает на строковый литерал, но здесь это не проблема.]

1 голос
/ 19 апреля 2011

Давайте попробуем еще раз:

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;
}

Это работает?

0 голосов
/ 19 апреля 2011

Это потому, что литеральные строки являются константными в C ++, а вы инициализируете их неконстантным указателем:

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

Однако это может вызвать проблемы, если md5_process принимает неконстантные char*,в этом случае вам придется привести к неконстантному:

md5_process(&md, const_cast<char*>(in), strlen(in));
...