C와 C++ 에서의 : const unsigned char * 에 대한 질문 입니다.

sabihanl의 이미지

일단 저는 현재 MD5해쉬 값을 얻어 내기 위하여
openssl의 md5 함수를 이용 했는데요
gcc로 잘 컴파일 되던 구문이 g++로는 컴파일 에러가 나서 질문 올려 봅니다.

소스는 아래와 같습니다.

---------------------------------------

1: #include
2: #include
3:
4: int main()
5: {
6: unsigned char *str="한글정보검색시스템";
7: unsigned char md5[16];
8: unsigned long len;
9: int i;
10:
11: memset(md5, 0, 16);
12:
13: len = strlen(str);
14: MD5(str, len, md5);
15:
16: for(i = 0; i < 16; i ++)
17: printf("%02x ", md5[i]);
18:
19: return 0;
20: }
-------------------------------------------------
man page에 MS5()에대한 설명은
아래와 같습니다.
-------------------------------------------------
#include

unsigned char *MD5(const unsigned char *d, unsigned long n,
unsigned char *md);
-------------------------------------------------

컴파일은 gcc md5.c -lssl이라고 했는데 문제 없이 컴파일 되던것이
C++소스에 이 내용을 추가 한뒤 g++ md5.c -lssl 로 컴파일 하니
아래와 같은 에러가 뜹니다.
--------------------------------------------------
md5.c: In function 'int main()':
md5.c:6: error: invalid conversion from 'const char*' to 'unsigned char*'
md5.c:11: error: 'memset' was not declared in this scope
md5.c:13: error: 'strlen' was not declared in this scope
---------------------------------------------------
다른 에러야 그렇다 치고 invalid conversion 에러가 나오는데
도저히 이해를 못하겠습니다.
함수 인자로 const char *넣는것은 함수 내부에서의 문자열이 수정되지 않는 다는 것을 보장 하기 위함이고
단지 char *와 같이 인자를 전달하고 그냥 쓰기만 하는 것인데
g++로 컴파일 할 때 왜 컴파일이 안되는지 이유를 아시는지요..?

혹시 아신다면 답변과 어떻게 수정해야 할지 알려 주시면 감사하겠습니다.
아.. 그리고 -lssl이라고 라이브러리를 지정해서 같이 컴파일 해주는데.. 실제로 라리브러리 파일은 보통 리눅스의
어디에 위치 하는 것인지 아시면 알려주시면 감사하겠습니다.

워낙 코딩 초보다 보니 막막 합니다 ㅠ _ㅠ;

Fe.head의 이미지

형식 변환 에러군요.

unsigned char *str="한글정보검색시스템";

"한글정보검색시스템" 이것은 const char * 형입니다.
이것을 unsigned char * 로 변경하려니까 에러가 생긴 겁니다.

const char *str="한글정보검색시스템";
 
...
MD5((const unsigned char *)str, len, md5);

이렇게 해보세요.
-----------------------
과거를 알고 싶거든 오늘의 네 모습을 보아라. 그것이 과거의 너니라.
그리고 내일을 알고 싶으냐?
그러면 오늘의 너를 보아라. 그것이 바로 미래의 너니라.

고작 블로킹 하나, 고작 25점 중에 1점, 고작 부활동
"만약 그 순간이 온다면 그때가 네가 배구에 빠지는 순간이야"

vacancy의 이미지


unsigned char * 을 char * 로 바꿔도 그런가요 ?

sabihanl의 이미지

vacancy님 // 일단 아래 함수 원형은 라이브러리 형태라 수정을 할 수가 없어서 바꿀 수가 없습니다 ㅠ _ㅠ
Fe.head님 //

const char *str="한글정보검색시스템";
 
...
MD5((const unsigned char *)str, len, md5);

MD5((const unsigned char *)str, len, md5); 처럼 함수 호출부에서 캐스팅 하니 같은 에러가 나는데
const char *str=(unsigned char*)"문자열"; 이런식으로 애초에 캐스팅해서 문자열을 만드니 문제가 없네요
도저히 이해가 안되지만 ㅠ _ㅠ;; 암튼 Fe.head님 덕에 힌트 얻어서 문제는 어찌어찌 해결 되었습니다..

혹시 위 상황에 대하여 설명 해주실 분은 안계 신가요? 워낙 초보라 ㅠ _ㅠ

아무튼 두분 답변 정말 감사 합니다 ^^ /

hys545의 이미지

c언어는 자동으로 형변환해주는 것도 c++에서는 자동으로 안해주는 경우가 많습니다
그 이유는 자동 형변환 할경우 데이타 손실등이 발생해서 실행시 에러 날 가능성이 있기 때문입니다
해결책은
1.위와 같이 사용자가 직접 형변환을 해준다.
문제는 이런경우 실행시 에러 날 가능성이 잇습니다

2, 데이타 형을 일치시켜준다.. 처음부터 c++로 작성되었으면 별 문제 없습니다. c언어로 작성된 라이브러리 사용할 경우 1번 방법을 사용하는 방법밖에는 없습니다.

즐린

cruega의 이미지

삭제가 안돼다니

md5.c:6: error: invalid conversion from 'const char*' to 'unsigned char*'

-> 이 error 는 앞에 언급된것 처럼 string 은 data 로 read only 영역에 적재되기 때문에 자동으로 const char * 타입을 가지게 됨으로 발생.

따라서 저것만 바껴도 별문제가 없는걸로 보임.

unsigned char *str= (unsigned char *) "한글정보검색시스템";
ex)
strlen 도 const char * 를 인자로 취함.

이러한 함수 원형에 const 라고 명시한 이유는 해당 함수 내부에서 const 인자를 변경하지 않음을 나타냄.

이에 굳이 인자가 될 변수가 const 로 선언되지 않더라도 형만 맞으면 MD5(const unsigned char *, ...); 의 인자로 사용할 수 있는걸로 암.

cppig1995의 이미지

생성시에 캐스트를 하는 것이 가장 좋은 방법인 것 같습니다.
많은 분들이 const 문제라고 생각하시는데, 저는 char*를 unsigned char*로 형변환하는 것에서
문제가 발생한다고 봅니다. 왜냐면 T*는 const T*로 자동으로 형변환되거든요.
(그렇지 않다면 char *s = "TheDreamImplementation"; printf("%d", strlen(s)); 에도 오류가 나게 됩니다.)
그걸 한번 고려해보시고요.
그리고, 위 모든 방법이 알맞지 않다고 생각하시는 경우에는 일단 편법이라도...
void*로 형변환했다가 함수에서 그토록 원하는 const unsigned char*로 다시 변환해보세요.



It's High Noon...

Real programmers /* don't */ comment their code.
If it was hard to write, it should be /* hard to */ read.

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.