C와 C++ 에서의 : const unsigned char * 에 대한 질문 입니다.
일단 저는 현재 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이라고 라이브러리를 지정해서 같이 컴파일 해주는데.. 실제로 라리브러리 파일은 보통 리눅스의
어디에 위치 하는 것인지 아시면 알려주시면 감사하겠습니다.
워낙 코딩 초보다 보니 막막 합니다 ㅠ _ㅠ;
형식 변환
형식 변환 에러군요.
"한글정보검색시스템" 이것은 const char * 형입니다.
이것을 unsigned char * 로 변경하려니까 에러가 생긴 겁니다.
이렇게 해보세요.
-----------------------
과거를 알고 싶거든 오늘의 네 모습을 보아라. 그것이 과거의 너니라.
그리고 내일을 알고 싶으냐?
그러면 오늘의 너를 보아라. 그것이 바로 미래의 너니라.
고작 블로킹 하나, 고작 25점 중에 1점, 고작 부활동
"만약 그 순간이 온다면 그때가 네가 배구에 빠지는 순간이야"
unsigned char * 을 char *
unsigned char * 을 char * 로 바꿔도 그런가요 ?
음..
vacancy님 // 일단 아래 함수 원형은 라이브러리 형태라 수정을 할 수가 없어서 바꿀 수가 없습니다 ㅠ _ㅠ
Fe.head님 //
MD5((const unsigned char *)str, len, md5); 처럼 함수 호출부에서 캐스팅 하니 같은 에러가 나는데
const char *str=(unsigned char*)"문자열"; 이런식으로 애초에 캐스팅해서 문자열을 만드니 문제가 없네요
도저히 이해가 안되지만 ㅠ _ㅠ;; 암튼 Fe.head님 덕에 힌트 얻어서 문제는 어찌어찌 해결 되었습니다..
혹시 위 상황에 대하여 설명 해주실 분은 안계 신가요? 워낙 초보라 ㅠ _ㅠ
아무튼 두분 답변 정말 감사 합니다 ^^ /
아마 c++은 형변환이 c보다 엄격해서 그런거 같습니다.
c언어는 자동으로 형변환해주는 것도 c++에서는 자동으로 안해주는 경우가 많습니다
그 이유는 자동 형변환 할경우 데이타 손실등이 발생해서 실행시 에러 날 가능성이 있기 때문입니다
해결책은
1.위와 같이 사용자가 직접 형변환을 해준다.
문제는 이런경우 실행시 에러 날 가능성이 잇습니다
2, 데이타 형을 일치시켜준다.. 처음부터 c++로 작성되었으면 별 문제 없습니다. c언어로 작성된 라이브러리 사용할 경우 1번 방법을 사용하는 방법밖에는 없습니다.
즐린
삭제가 안돼다니
삭제가 안돼다니
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 *, ...); 의 인자로 사용할 수 있는걸로 암.
생성시에 캐스트를
생성시에 캐스트를 하는 것이 가장 좋은 방법인 것 같습니다.
많은 분들이 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.
댓글 달기