달력

112024  이전 다음

  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30

stdlib.h ............................................................................

 

형변환 함수

 

#include <stdlib.h>

 

문자열을 숫자로 변환

int atoi(char *source_buffer)

long atol(char *source_buffer)

float atof(char *source_buffer)

 

숫자를 문자열로 변환

char *itoa(int value, char *string, int radix)

char *ltoa(long value, char *string, int radix)

char *ftoa(float value, char *string, int radix)

 

실수형 숫자를 문자열로 변환

char *ecvt(double value, int count, int *dec, int *sign)

 

부동소수점 숫자를 문자열로 변환

char *fcvt(double value, int count, int *dec, int *sign)

char *gcvt(double value, int digits, char *buffer)

 

sccanf

 

scanf처럼 키보드 입력을 받지 않고, 문자열에서 데이터를 추출 한다.

 

format :

int sscanf(const char* buffer, const char* format, [...address]);

 

#include <stdio.h>
#include <string.h>


char str[128];

int i,j,k;

 

  strcpy(str, "One = 1, Two = 2, Three = 3");
  sscanf(str,"One = %d, Two = %d, Three = %d", &i, &j, &k);
  printf("%d, %d, %d \n", i, j, k);

 

 

wcscpy  ............................................................................

 

copy a wide-character string

 

#include <wchar.h>

wchar_t *wcscpy(wchar_t *ws1, const wchar_t *ws2);

 


 

 

MFC ............................................................................

 

 

Preprocessor Directives for Generic-Text Mappings
# define Compiled version Example

_UNICODE

Unicode (wide-character)

_tcsrev maps to _wcsrev

_MBCS

Multibyte-character

_tcsrev maps to _mbsrev

None (the default: neither _UNICODE nor _MBCS defined)

SBCS (ASCII)

_tcsrev maps to strrev

 

 

Generic-Text Data Type Mappings
Generic-Text Data Type Name _UNICODE & _MBCS Not Defined _MBCS Defined _UNICODE Defined

_TCHAR

char

char

wchar_t

_TINT

int

int

wint_t

_TSCHAR

signed char

signed char

wchar_t

_TUCHAR

unsigned char

unsigned char

wchar_t

_TXCHAR

char

unsigned char

wchar_t

_T or _TEXT

No effect (removed by preprocessor)

No effect (removed by preprocessor)

L (converts following character or string to its Unicode counterpart)

 

 

 

UNICODE를 정의해주느냐 아니냐에 따라 컴파일만 따로 해주면 되니까요.

 

                    ANSI           UNICODE         TCHAR

헤더파일       string.h         wchar.h          tchar.h

문자             'A'                L'A'               _T('A')

문자열          "ABC"            L"ABC"           _T("ABC")

문자열카피    strcpy            wcscpy          _tcscpy

문자열길이    strlen             wcslen           _tcslen

문자열출력    printf              wprintf            _tprinf

파일열기       fopen             wfopen           _tfopn

 

MultiByteToWideChar()  : ANSI -> UNICODE

WideCharToMultiByte()  : UNICODE -> ANSI

 

 

MBCS와 UTF-8 변환 예 :

 

char buffer[20];
WCHAR Unicode[20];
char UTF8code[20];


 

int nUnicodeSize = MultiByteToWideChar(CP_ACP, 0, lpID, strlen(lpID), Unicode,sizeof(Unicode));
int nUTF8codeSize = WideCharToMultiByte(CP_UTF8, 0, Unicode, nUnicodeSize, UTF8code, sizeof(UTF8code), NULL, NULL);
nUnicodeSize = MultiByteToWideChar(CP_UTF8, 0, UTF8code, nUTF8codeSize, Unicode,sizeof(Unicode));
memcpy(buffer, UTF8code, nUTF8codeSize);

 

..........................................................................

 

출처 : http://msdn.microsoft.com/en-us/library/tsbaswba%28VS.80%29.aspx

 

Generic-Text Routine Mappings

Generic-text
routine name
SBCS (_UNICODE &
MBCS not defined)
_MBCS
defined
_UNICODE defined

_cgetts

_cgets

_cgets

_cgetws

_cgetts_s

_cgets_s

_cgets_s

_cgetws_s

_cputts

_cputs

_cputs

_cputws

_fgettc

fgetc

fgetc

fgetwc

_fgettchar

_fgetchar

_fgetchar

_fgetwchar

_fgetts

fgets

fgets

fgetws

_fputtc

fputc

fputc

fputwc

_fputtchar

_fputchar

_fputchar

_fputwchar

_fputts

fputs

fputs

fputws

_ftprintf

fprintf

fprintf

fwprintf

_ftprintf_s

fprintf_s

fprintf_s

fwprintf_s

_ftscanf

fscanf

fscanf

fwscanf

_ftscanf_s

fscanf_s

fscanf_s

fwscanf_s

_gettc

getc

getc

getwc

_gettch

_getch

_getch

_getwch

_gettchar

getchar

getchar

getwchar

_gettche

_getche

_getche

_getwche

_getts

gets

gets

getws

_getts_s

gets_s

gets_s

getws_s

_istalnum

isalnum

_ismbcalnum

iswalnum

_istalpha

isalpha

_ismbcalpha

iswalpha

_istascii

isascii

isascii

iswascii

_istcntrl

iscntrl

iscntrl

iswcntrl

_istdigit

isdigit

_ismbcdigit

iswdigit

_istgraph

isgraph

_ismbcgraph

iswgraph

_istlead

Always returns false

_ismbblead

Always returns false

_istleadbyte

Always returns false

isleadbyte

Always returns false

_istlegal

Always returns true

_ismbclegal

Always returns true

_istlower

islower

_ismbclower

iswlower

_istprint

isprint

_ismbcprint

iswprint

_istpunct

ispunct

_ismbcpunct

iswpunct

_istspace

isspace

_ismbcspace

iswspace

_istupper

isupper

_ismbcupper

iswupper

_istxdigit

isxdigit

isxdigit

iswxdigit

_itot

_itoa

_itoa

_itow

_itot_s

_itoa_s

_itoa_s

_itow_s

_ltot

_ltoa

_ltoa

_ltow

_ltot_s

_ltoa_s

_ltoa_s

_ltow_s

_puttc

putc

putc

putwc

_puttch

_putch

_putch

_putwch

_puttchar

putchar

putchar

putwchar

_putts

puts

puts

_putws

_sctprintf

_scprintf

_scprintf

_scwprintf

_sntprintf

_snprintf

_snprintf

_snwprintf

_sntprintf_s

_snprintf_s

_snprintf_s

_snwprintf_s

_sntscanf

_snscanf

_snscanf

_snwscanf

_sntscanf_s

_snscanf_s

_snscanf_s

_snwscanf_s

_stprintf

sprintf

sprintf

swprintf

_stprintf_s

sprintf_s

sprintf_s

swprintf_s

_stscanf

sscanf

sscanf

swscanf

_stscanf_s

sscanf_s

sscanf_s

swscanf_s

_taccess

_access

_access

_waccess

_taccess_s

_access_s

_access_s

_waccess_s

_tasctime

asctime

asctime

_wasctime

_tasctime_s

asctime_s

asctime_s

_wasctime_s

_tccmp

Maps to macro or inline function

_mbsncmp

Maps to macro or inline function

_tccpy

Maps to macro or inline function

_mbccpy

Maps to macro or inline function

_tccpy_s

strcpy_s

_mbccpy_s

wcscpy_s

_tchdir

_chdir

_chdir

_wchdir

_tclen

Maps to macro or inline function

_mbclen

Maps to macro or inline function

_tchmod

_chmod

_chmod

_wchmod

_tcprintf

_cprintf

_cprintf

_cwprintf

_tcprintf_s

_cprintf_s

_cprintf_s

_cwprintf_s

_tcreat

_creat

_creat

_wcreat

_tcscanf

_cscanf

_cscanf

_cwscanf

_tcscanf_s

_cscanf_s

_cscanf_s

_cwscanf_s

_tcscat

strcat

_mbscat

wcscat

_tcscat_s

strcat_s

_mbscat_s

wcscat_s

_tcschr

strchr

_mbschr

wcschr

_tcsclen

strlen

_mbslen

wcslen

_tcsclen_s

strlen_s

_mbslen_s

wcslen_s

_tcscmp

strcmp

_mbscmp

wcscmp

_tcscoll

strcoll

_mbscoll

wcscoll

_tcscpy

strcpy

_mbscpy

wcscpy

_tcscpy_s

strcpy_s

_mbscpy_s

wcscpy_s

_tcscspn

strcspn

_mbscspn

wcscspn

_tcsdec

_strdec

_mbsdec

_wcsdec

_tcsdup

_strdup

_mbsdup

_wcsdup

_tcserror

strerror

strerror

_wcserror

_tcserror_s

strerror_s

strerror_s

_wcserror_s

_tcsftime

strftime

strftime

wcsftime

_tcsicmp

_stricmp

_mbsicmp

_wcsicmp

_tcsicoll

_stricoll

_mbsicoll

_wcsicoll

_tcsinc

_strinc

_mbsinc

_wcsinc

_tcslen

strlen

strlen

wcslen

_tcslen_s

strlen_s

strlen_s

wcslen_s

_tcslwr

_strlwr

_mbslwr

_wcslwr

_tcslwr_s

_strlwr_s

_mbslwr_s

_wcslwr_s

_tcsnbcnt

_strncnt

_mbsnbcnt

_wcsncnt

_tcsncat

strncat

_mbsnbcat

wcsncat

_tcsncat_s

strncat_s

_mbsnbcat_s

wcsncat_s

_tcsnccat

strncat

_mbsncat

wcsncat

_tcsnccmp

strncmp

_mbsncmp

wcsncmp

_tcsnccmp_s

strncmp_s

_mbsncmp_s

wcsncmp_s

_tcsnccoll

_strncoll

_mbsncoll

_wcsncoll

_tcsncmp

strncmp

_mbsnbcmp

wcsncmp

_tcsnccnt

_strncnt

_mbsnccnt

_wcsncnt

_tcsnccpy

strncpy

_mbsncpy

wcsncpy

_tcsnccpy_s

strncpy_s

_mbsncpy_s

wcsncpy_s

_tcsncicmp

_strnicmp

_mbsnicmp

_wcsnicmp

_tcsncicoll

_strnicoll

_mbsnicoll

_wcsnicoll

_tcsncpy

strncpy

_mbsnbcpy

wcsncpy

_tcsncpy_s

strncpy_s

_mbsnbcpy_s

wcsncpy_s

_tcsncset

_strnset

_mbsnset

_wcsnset

_tcsnextc

_strnextc

_mbsnextc

_wcsnextc

_tcsnicmp

_strnicmp

_mbsnbicmp

_wcsnicmp

_tcsnicoll

_strnicoll

_mbsnbicoll

_wcsnicoll

_tcsninc

_strninc

_mbsninc

_wcsninc

_tcsnccnt

_strncnt

_mbsnccnt

_wcsncnt

_tcsnset

_strnset

_mbsnbset

_wcsnset

_tcspbrk

strpbrk

_mbspbrk

wcspbrk

_tcsspnp

_strspnp

_mbsspnp

_wcsspnp

_tcsrchr

strrchr

_mbsrchr

wcsrchr

_tcsrev

_strrev

_mbsrev

_wcsrev

_tcsset

_strset

_mbsset

_wcsset

_tcsspn

strspn

_mbsspn

wcsspn

_tcsstr

strstr

_mbsstr

wcsstr

_tcstod

strtod

strtod

wcstod

_tcstoi64

_strtoi64

_strtoi64

_wcstoi64

_tcstok

strtok

_mbstok

wcstok

_tcstok_s

strtok_s

_mbstok_s

wcstok_s

_tcstol

strtol

strtol

wcstol

_tcstoui64

_strtoui64

_strtoui64

_wcstoui64

_tcstoul

strtoul

strtoul

wcstoul

_tcsupr

_strupr

_mbsupr

_wcsupr

_tcsupr_s

_strupr_s

_mbsupr_s

_wcsupr_s

_tcsxfrm

strxfrm

strxfrm

wcsxfrm

_tctime

ctime

ctime

_wctime

_tctime_s

ctime_s

ctime_s

_wctime_s

_tctime32

_ctime32

_ctime32

_wctime32

_tctime32_s

_ctime32_s

_ctime32_s

_wctime32_s

_tctime64

_ctime64

_ctime64

_wctime64

_tctime64_s

_ctime64_s

_ctime64_s

_wctime64_s

_texecl

_execl

_execl

_wexecl

_texecle

_execle

_execle

_wexecle

_texeclp

_execlp

_execlp

_wexeclp

_texeclpe

_execlpe

_execlpe

_wexeclpe

_texecv

_execv

_execv

_wexecv

_texecve

_execve

_execve

_wexecve

_texecvp

_execvp

_execvp

_wexecvp

_texecvpe

_execvpe

_execvpe

_wexecvpe

_tfdopen

_fdopen

_fdopen

_wfdopen

_tfindfirst

_findfirst

_findfirst

_wfindfirst

_tfindnext

_findnext

_findnext

_wfindnext

_tfindnext32

_findnext32

_findnext32

_wfindnext32

_tfindnext64

_findnext64

_findnext64

_wfindnext64

_tfindnexti64

_findnexti64

_findnexti64

_wfindnexti64

_tfindnexti6432

_findnexti6432

_findnexti6432

_wfindnexti6432

_tfindnext32i64

_findnext32i64

_findnext32i64

_wfindnext32i64

_tfopen

fopen

fopen

_wfopen

_tfopen_s

fopen_s

fopen_s

_wfopen_s

_tfreopen

freopen

freopen

_wfreopen

_tfreopen_s

freopen_s

freopen_s

_wfreopen_s

_tfsopen

_fsopen

_fsopen

_wfsopen

_tfullpath

_fullpath

_fullpath

_wfullpath

_tgetcwd

_getcwd

_getcwd

_wgetcwd

_tgetdcwd

_getdcwd

_getdcwd

_wgetdcwd

_tgetenv

getenv

getenv

_wgetenv

_tgetenv_s

getenv_s

getenv_s

_wgetenv_s

_tmain

main

main

wmain

_tmakepath

_makepath

_makepath

_wmakepath

_tmakepath_s

_makepath_s

_makepath_s

_wmakepath_s

_tmkdir

_mkdir

_mkdir

_wmkdir

_tmktemp

_mktemp

_mktemp

_wmktemp

_tmktemp_s

_mktemp_s

_mktemp_s

_wmktemp_s

_topen

_open

_open

_wopen

_topen_s

_open_s

_open_s

_wopen_s

_totlower

tolower

_mbctolower

towlower

_totupper

toupper

_mbctoupper

towupper

_tperror

perror

perror

_wperror

_tpopen

_popen

_popen

_wpopen

_tprintf

printf

printf

wprintf

_tprintf_s

printf_s

printf_s

wprintf_s

_tputenv

_putenv

_putenv

_wputenv

_tputenv_s

_putenv_s

_putenv_s

_wputenv_s

_tremove

remove

remove

_wremove

_trename

rename

rename

_wrename

_trmdir

_rmdir

_rmdir

_wrmdir

_tsearchenv

_searchenv

_searchenv

_wsearchenv

_tsearchenv_s

_searchenv_s

_searchenv_s

_wsearchenv_s

_tscanf

scanf

scanf

wscanf

_tscanf_s

scanf_s

scanf_s

wscanf_s

_tsetlocale

setlocale

setlocale

_wsetlocale

_tsopen

_sopen

_sopen

_wsopen

_tsopen_s

_sopen_s

_sopen_s

_wsopen_s

_tspawnl

_spawnl

_spawnl

_wspawnl

_tspawnle

_spawnle

_spawnle

_wspawnle

_tspawnlp

_spawnlp

_spawnlp

_wspawnlp

_tspawnlpe

_spawnlpe

_spawnlpe

_wspawnlpe

_tspawnv

_spawnv

_spawnv

_wspawnv

_tspawnve

_spawnve

_spawnve

_wspawnve

_tspawnvp

_spawnvp

_spawnvp

_wspawnvp

_tspawnvpe

_spawnvpe

_spawnvpe

_wspawnvpe

_tsplitpath

_splitpath

_splitpath

_wsplitpath

_tstat

_stat

_stat

_wstat

_tstat32

_stat32

_stat32

_wstat32

_tstati32

_stati32

_stati32

_wstati32

_tstat64

_stat64

_stat64

_wstat64

_tstati64

_stati64

_stati64

_wstati64

_tstof

atof

atof

_wtof

_tstoi

atoi

atoi

_wtoi

_tstoi64

_atoi64

_atoi64

_wtoi64

_tstol

atol

atol

_wtol

_tstrdate

_strdate

_strdate

_wstrdate

_tstrdate_s

_strdate_s

_strdate_s

_wstrdate_s

_tstrtime

_strtime

_strtime

_wstrtime

_tstrtime_s

_strtime_s

_strtime_s

_wstrtime_s

_tsystem

system

system

_wsystem

_ttempnam

_tempnam

_tempnam

_wtempnam

_ttmpnam

tmpnam

tmpnam

_wtmpnam

_ttmpnam_s

tmpnam_s

tmpnam_s

_wtmpnam_s

_ttoi

atoi

atoi

_wtoi

_ttoi64

_atoi64

_atoi64

_wtoi64

_ttol

atol

atol

_wtol

_tunlink

_unlink

_unlink

_wunlink

_tutime

_utime

_utime

_wutime

_tutime32

_utime32

_utime32

_wutime32

_tutime64

_utime64

_utime64

_wutime64

_tWinMain

WinMain

WinMain

wWinMain

_ui64tot

_ui64toa

_ui64toa

_ui64tow

_ui64tot_s

_ui64toa_s

_ui64toa_s

_ui64tow_s

_ultot

_ultoa

_ultoa

_ultow

_ultot_s

_ultoa_s

_ultoa_s

_ultow_s

_ungettc

ungetc

ungetc

ungetwc

_ungettch

_ungetch

_ungetch

_ungetwch

_vftprintf

vfprintf

vfprintf

vfwprintf

_vftprintf_s

vfprintf_s

vfprintf_s

vfwprintf_S

_vsctprintf

_vscprintf

_vscprintf

_vscwprintf

_vsctprintf_s

_vscprintf_s

_vscprintf_s

_vscwprintf_S

_vsntprintf

_vsnprintf

_vsnprintf

_vsnwprintf

_vsntprintf_s

_vsnprintf_s

_vsnprintf_s

_vsnwprintf_s

_vstprintf

vsprintf

vsprintf

vswprintf

_vstprintf_s

vsprintf_s

vsprintf_s

vswprintf_s

_vtprintf

vprintf

vprintf

vwprintf

_vtprintf_s

vprintf_s

vprintf_s

vwprintf_s

 

Generic-Text Data Type Mappings
Generic-text data type name SBCS (_UNICODE, _MBCS not defined) _MBCS defined _UNICODE defined

_TCHAR

char

char

wchar_t

_tfinddata_t

_finddata_t

_finddata_t

_wfinddata_t

_tfinddata64_t

__finddata64_t

__finddata64_t

__wfinddata64_t

_tfinddatai64_t

_finddatai64_t

_finddatai64_t

_wfinddatai64_t

_TINT

int

int

wint_t

_TSCHAR

signed char

signed char

wchar_t

_TUCHAR

unsigned char

unsigned char

wchar_t

_TXCHAR

char

unsigned char

wchar_t

_T or _TEXT

No effect (removed by preprocessor)

No effect (removed by preprocessor)

L (converts following character or string to its Unicode counterpart)

 

 

Locale-Dependent Routines
Routine Use setlocale category setting dependence

atof, _wtof_l, _wtof, _atof_l

Convert character to floating-point value

LC_NUMERIC

atoi, _wtoi_l, _wtoi, _atoi_l

Convert character to integer value

LC_NUMERIC

_atoi64, _wtoi64_l, _wtoi64, _atoi64_l

Convert character to 64-bit integer value

LC_NUMERIC

atol, _wtol_l, _wtol, _atol_l

Convert character to long value

LC_NUMERIC

_atodbl, _atoflt_l, _atoflt, _atoldbl_l, _atoldbl, _atodbl_l

Convert character to double-long value

LC_NUMERIC

Routines is

Test given integer for particular condition.

LC_CTYPE

isleadbyte, _isleadbyte_l

Test for lead byte

LC_CTYPE

localeconv

Read appropriate values for formatting numeric quantities

LC_MONETARY, LC_NUMERIC

MB_CUR_MAX

Maximum length in bytes of any multibyte character in current locale (macro defined in STDLIB.H)

LC_CTYPE

_mbccpy_s, _mbccpy_l, _mbccpy, _mbccpy_s_l

Copy one multibyte character

LC_CTYPE

_mbclen, _mblen_l,  mblen

Validate and return number of bytes in multibyte character

LC_CTYPE

strlen, _mbstrlen_l, _mbstrlen, _mbslen_l, _mbslen, wcslen_l, wcslen, strlen_l

For multibyte-character strings: validate each character in string; return string length

LC_CTYPE

mbstowcs_s, _mbstowcs_l,mbstowcs,_mbstowcs_s_l

Convert sequence of multibyte characters to corresponding sequence of wide characters

LC_CTYPE

mbtowc, _mbtowc_l

Convert multibyte character to corresponding wide character

LC_CTYPE

printf functions

Write formatted output

LC_NUMERIC (determines radix character output)

scanf functions

Read formatted input

LC_NUMERIC (determines radix character recognition)

setlocale, _wsetlocale

Select locale for program

Not applicable

_mbscoll_l _wcscoll_l, _strcoll_l, _mbscoll, wcscoll,strcoll

Compare characters of two strings

LC_COLLATE

_mbsicmp_l,_wcsicmp_l, _stricmp_l, _mbsicmp, _wcsicmp, _stricmp,

Compare two strings without regard to case

LC_CTYPE

_mbsicoll_l,_wcsicoll_l, _stricoll_l, _mbsicoll, _wcsicoll,_stricoll,

Compare characters of two strings (case insensitive)

LC_COLLATE

_mbsncoll_l,_wcsncoll_l, _strncoll_l, _mbsncoll, _wcsncoll, _strncoll,

Compare first n characters of two strings

LC_COLLATE

_mbsnicmp_l,_wcsnicmp_l, _strnicmp_l, _mbsnicmp, _wcsnicmp, _strnicmp,

Compare characters of two strings without regard to case.

LC_CTYPE

_mbsnicoll_l,_wcsnicoll_l, _strnicoll_l, _mbsnicoll, _wcsnicoll, _strnicoll,

Compare first n characters of two strings (case insensitive)

LC_COLLATE

_wcsftime_l,_strftime_l, wcsftime, strftime,

Format date and time value according to supplied format argument

LC_TIME

_mbslwr_l,_wcslwr_l, _strlwr_l, _mbslwr, _wcslwr, _strlwr, _wcslwr_s_l,_wcslwr_s, _mbslwr_s_l, _mbslwr_s, _strlwr_s_l, _strlwr_s,

Convert, in place, each uppercase letter in given string to lowercase

LC_CTYPE

_wcstod_l, wcstod, _strtod_l,strtod,

Convert character string to double value

LC_NUMERIC (determines radix character recognition)

_wcstol_l,_strtol_l, wcstol,strtol,

Convert character string to long value

LC_NUMERIC (determines radix character recognition)

_wcstoul_l,wcstoul, _strtoul_l, strtoul,

Convert character string to unsigned long value

LC_NUMERIC (determines radix character recognition)

_wcsupr, _wcsupr_l, _mbsupr_l, _mbsupr, _strupr_l, _strupr, _wcsupr_s_l, _wcsupr_s, _mbsupr_s_l, _mbsupr_s, _strupr_s_l, _strupr_s,

Convert, in place, each lowercase letter in string to uppercase

LC_CTYPE

_wcsxfrm_l, _strxfrm_l, wcsxfrm, strxfrm,

Transform string into collated form according to locale

LC_COLLATE

_towlower_l, _tolower_l, towlower, _tolower,tolower,_mbctoupper_l, _mbctoupper, _mbctolower_l,_mbctolower,

Convert given character to corresponding lowercase character

LC_CTYPE

_towupper_l, _toupper_l, towupper, _toupper,toupper, _mbctoupper_l, _mbctoupper, _mbctolower_l,_mbctolower,

Convert given character to corresponding uppercase letter

LC_CTYPE

_wcstombs_l,wcstombs,_wcstombs_s_l,wcstombs_s,

Convert sequence of wide characters to corresponding sequence of multibyte characters

LC_CTYPE

_wctomb_l,wctomb,_wctomb_s_l,wctomb_s,

Convert wide character to corresponding multibyte character

LC_CTYPE


출처 : http://blog.naver.com/dolicom/10074808231
Posted by 위너즈
|

듀얼모니터를 사용하는 경우 윈도우나 마우스의 좌표가 음수(-)값이 나올 수 있다.
디스플레이 설정에서 우측의 모니터를 Primary모니터로 잡는 경우, 우측 모니터의 좌 상단이 (0,0)좌표가 되며, 왼쪽 모니터의 X좌표는 음수 값을 갖게 된다.

마우스나 윈도우의 좌표를 LPARAM의 전달하는 메시지의 경우,
보통 HIWORD(lParam), LOWORD(lParam)를 사용해서 좌표를 파싱하게 되는데

HIWORD()
LOWORD() 매크로의 경우, WORD값 즉 양수만을 리턴 하므로 정상적인 좌표가 계산되지 않는다.

이경우,

HIWORD() 대신 GET_X_LPARAM()
LOWORD() 대신 GET_Y_LPARAM()

을 사용하면 정상적인 좌표값을 얻울 수 있다.

 

GET_X_LPARAM()GET_Y_LPARAM()은 다음과 같이 정의 되어 있으며, <windowsx.h>에 정의되어 있다.

#define GET_X_LPARAM(lp) ((int)(short)LOWORD(lp))
#define GET_Y_LPARAM(lp) ((int)(short
)HIWORD(lp))

참고로 HIWORD() LOWORD()의 정의는 다음과 같다

#define HIWORD(l) ((WORD) (((DWORD) (l) >> 16) & 0xFFFF))
#define LOWORD(l) ((WORD) (l))

출처 : http://thepassion.tistory.com/32

Posted by 위너즈
|

Visual C++ 로 작성된 코드가 vs6, vs2003, vs2005, vs2008, vs2010 에서
error나 warning 없이 컴파일 되게 하려면 각기 다른 코드로 작성해야 하는데 
이것을 구분하기 위해서 따로 전처리기 변수를 정의할 필요 없이 _MSC_VER를 사용하면 된다.

_MSC_VER 로 Visual Studio 컴파일러 버전을 알 수 있으며
_MSC_VER 이 정의되어있지 않다면 Unix 계열의 C++로 판단할 수 있을 것 같다.

_MSC_VER
 _MSC_VER 값  컴파일러 버전  Visual Studio 버전
 ( _MSC_VER => 1000 )  4.0  
 ( _MSC_VER => 1100 )  5.0  
 ( _MSC_VER => 1200 )  6.0  vs6
 ( _MSC_VER => 1310 )  7.1  vs2003
 ( _MSC_VER => 1400 )  8.0  vs2005
 ( _MSC_VER => 1500 )  9.0  vs2008
 ( _MSC_VER => 1600 )  10.0  vs2010


사용예를 들자면 vs6에는 _tfopsn_s() 가 없어서 fopen()를 사용하면 vs2008에서 컴파일시 warning이 발생한다.
이때, _MSC_VER 를 사용해 컴파일러마다 다른 코드를 사용하게끔 만들 수 있다. 
 
#if defined( _MSC_VER )
    #if( _MSC_VER < 1310)    // vs6
        pFile = fopen(szFile, "r");
        if( pFile == NULL )
        {
            return false;
        }
        //
 
    #elif( _MSC_VER < 1400)  // vs2003
        pFile = _tfopen(szFile, _T("r"));
        if( pFile == NULL )
        {
            return false;
        }
        //
    #else                   // vs2005 이상
        errno_t eno = _tfopen_s(&pFile, szFile, _T("r"));
        if( pFile == NULL || eno != 0 )
        {
            return false;
        }
    #endif
#endif
컴파일러 버전별로 Static Library를 배포해야 할 경우 이런 코드가 나올 수 밖에 없다.
C++ Open Source 라이브러리 코드도 이런식으로 사용하기는 마찬가지.. 

출처 : http://yamoe.tistory.com/
Posted by 위너즈
|

C++에서 복사생성자의 전달인자 선언시 const를 붙여주지 않아도 상관없다. 그러나 & 선언은 반드시 해줘야 한다.

& 선언이 없다면 무한루프에 빠져 버리기 때문이다. 다행히 대부분의 컴파일러는 & 선언을 해주지 않으면 컴파일

오류를 발생시켜 준다. 참으로 고마운 일이 아닐 수 없다. 그렇다면 왜 무한루프에 빠지게 되는 것일까?

다음 코드를 보기 바란다.

위 소스에서 네모친 부분이 복사생성자를 호출하는 부분이다.

여기서 &를 넣지 않는다면, 이는 Call by Reference 가 아닌, Call by Value가 된다.

즉, 값을 복사하여 그 값을 참조한다는 뜻이다. 하지만 문제는 지금부터 시작이다.

AAA객체를 복사하기 위해서는 객체생성 순서에 따라서 메모리를 할당하고 값을 복사하여야 한다.

다시 말해서 생성자를 호출하여야 한다는 의미다.

복사생성자 호출 -> 인자로 넘어가는 객체의 복사 -> 생성자, 복사생성자 호출 -> 그 복사생성자 안에서 또다시 객체 복사 -> 복사생성자 호출 -> ... 무한반복 ...

이렇게 복사생성자의 형식인자를 생성해야 하기 때문에 무한루프에 빠지게 된다. 역시 원인은 &를 빼면 Call by Value 라는 점에 있고, 레퍼런스를 쓰는 이유 중 하나이기도 하다.

 

※ 참고로 레퍼런스(&)를 사용한 Call by Reference로 인자를 넘겨주는 이유는 다음과 같이 크게 2가지이다.

1. &를 사용하지 않고 포인터를 사용하면 포인터 연산이 가능하기 때문에 잘못된 메모리 접근을 할 가능성이 높아진다.

    아래의 코드는 에러를 나타낼 것이다.

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

 void swap(int *a, int *b)

 {

        int temp = *a;

        a++;    // 잘못 들어간 코드

        *a = *b;

        *b = temp;

}

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

경우에 따라서는 포인터 연산이 가능하다는 것이 단점으로 작용한다.

 

2. 약간의 성능향상이 가능하다. 

   Call by Value로 크기가 큰 구조체같은 데이터를 함수 인자로 넘겨주면 함수의 호출이 부담스러울 수 밖에 없다.

   Call by Value의 기본 방식이 복사이기 때문이다.

   이러한 부담을 레퍼런스가 해결해 줄 수 있다. 레퍼런스의 형태로 받게 되면, 변수 주소만 복사해 가는 것이지, 데이터 자체가 복사되는 것이 아니기 때문이다.

→ 그렇다면, 레퍼런스(&)를 사용하여 Call by Reference로 함수 인자를 넘기는 것이 무조건 좋은 것인가??

   꼭 그렇지는 않다. 다음의 코드를 보자

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

void swap(int &a, int &b)

{

        int temp = a;

        a = b;

        b = temp;

}

int main(void)

{

        ...

        swap(val1, val2); 

        ...

}

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

   대충 눈치를 채셨겠지만, 이것만 봐서는 도대체 이 swap 함수가 Call by Value인지 Call by Reference인지 감을 잡지 못한다.
   프로그램의 길이가 엄청 긴 경우에는 더욱 헷갈릴 것이다.

   Call by Reference의 적절한 사용은 프로그래머의 선택이다. ^^

출처 : http://blog.naver.com/damby0?Redirect=Log&logNo=50023611792

'Programming > C++' 카테고리의 다른 글

C/C++언어 함수들  (0) 2011.08.22
교차 포함 시 대량의 오류가 발생하는 경우  (0) 2011.04.26
Posted by 위너즈
|
Java에서 Thread를 동기화 하는 방법. synchronized를 사용하면 된다. 아래 코드를 참조.
class A extends Thread
{
	private int value = 0;
	public synchronized void setValue(int var)
	{
		value = var;
	}
	public void run()
	{
		//synchronized로 block된 부분은 동기화처리가 된다.
		synchronized (this)
		{
			//처리할 코드
		}
	}
}

public class Test
{
	public station void main(String[] ar)
	{
		A _thread = new A();
		_thread.start();	//run thread
	}
}

'Programming > JAVA' 카테고리의 다른 글

Runnable, Thread 차이  (0) 2011.08.24
Posted by 위너즈
|
[DOM(Document Object Model) Parser]

특징 : Element를 모두 Tree 구조로 메모리에 넣어 두고 사용
장점 : 메모리에 Tree구조로 정보가 들어있기 때문에 한번 파싱해 두면
         아무때나 얻고 싶은 Element에 대한 정보를 얻을 수 있다.
단점 : 메모리의 소모가 다른 방법보다 많음


[SAX(Simple API for XML) Parser]

특징 : 이벤트 기반의 파서로 문서의 시작과 끝, Element의 시작과 끝, Element의 내용 등
         Element Tag의 이름에 따라 각각을 처리하는 메소드를 두어 파싱함
장점 : 라인by라인으로 파싱하기 때문에 파싱하는데 일정한(적은) 메모리만 소요
단점 : 파싱시 그냥 지나갔던 Element의 정보를 얻고 싶으면 다시 파싱해야함.


[Pull Parser]

특징 : SAX와 같이 이벤트 기반의 파서이지만, SAX와 달리 문서에 대한 모든 파싱을 하지 않고도
         특정 부분까지의 파싱내용을 활용할 수 있음.(parser.next()를 해줘야 함)
장점 : 원하는 부분까지만 파싱할 수 있는 장점.
단점 : SAX의 단점 + SAX보다 약간느림.

출처 : http://www.androidpub.com/ 토미님의 글
Posted by 위너즈
|

동기화를 위한 커널 객체의 특징

 • 커널 객체를 사용한 동기화의 경우 Signaled와 Nonsignaled의 두 가지 상태 중 하나로 존재하며, 동기화 객체가
   Signaled될 때까지 이 커널 객체를 사용하려는 스레드는 대기하고 있게 된다.

 • 프로세스를 생성하면 그 프로세스 내에 존재하는 커널 동기화 객체는 Nonsignaled 상태로 있게 되고,
   WaitForSingleObject()를 사용하여 이 커널 객체가 Signaled 될 때까지 기다릴 수 있으며, 프로세스 내에 존재하는
   커널 객체가 Signaled되는 시저은 그 프로세스가 종료하는 시점이 된다.
 • 유저 어플리케이션에서 모든 커널 객체가 핸들을 통하여 액세스되듯이 동기화를 위한 커널 객체 또한 핸들을
   사용하여 엑세스하게 된다. 그리고 이들 동기화 객체들은 모두 WaitForSingleObject() 또는
   WaitForMultipleObject()를 사용하여 그 객체가 Signaled될 때까지 기다릴 수 있게 된다.

출처 : Windows 구조와 원리 그리고 Codes

Posted by 위너즈
|

1. 크리티컬 섹션(Critical Section)이란?

 - 유저레벨 어플리케이션 작성 시 가장 간단하게 상요할 수 있는 방법이다.

 - 유저레벨의 동기화 방법 중 유일하게 커널 객체를사용하지 않으며 그 내부 구조가 단순하기 때문에
   동기화 처리를 하는 데 있어서 속도가 빠르다는 장점이 있으며 동일한 프로세스내에서만 사용할 수 있다는 제약이
   있다.

 - 크리티컬 섹션은 커널 객체를 사용하지 않기 때문에 핸들을 사용하지 않고 대신 CRITICAL_SECTION라는 타입을
   정의하여 사용하게 되며, 아래 4가지 Win32 API를 사용하여 동기화를 수행하게 된다.

     ◦VOID InitializeCriticalSection(LRCRITICAL_SECTION IpCriticalSection);
     ◦VOID DeleteCriticalSection(LRCRITICAL_SECTION IpCriticalSection);
     ◦VOID EnterCriticalSection(LRCRITICAL_SECTION IpCriticalSection);
     ◦VOID LeaveCriticalSection(LRCRITICAL_SECTION IpCriticalSection);
   ※ 커널 객체를 사용하지 않는 동기화 객체는 크리티컬 섹션뿐이며 뮤택스를 포함한 동기화 객체들,
      스레드(Thread), 파일(File)들까지도 동기화를 위한 커널 객체를 포함하고 있다.
      http://winnerz.tistory.com/

2. 뮤텍스(Mutex)란?

 - 뮤텍스는 최초에 Signaled 상태로 생성되어지며, WaitForSingleObject()와 같은 대기 함수를 호출함으로써
   NonSignaled 상태가 된다. WaitForSingleObject()와 같은 대기 함수에 대한 최초의 스레드 접근은 그 상태가
   Signaled이므로 스레드가 대기없이 해당 코드 영역으로 진입하게 되며, 이 진입이 일어난 후에는 뮤텍스의 상태가
   NonSignaled로 되므로 이후에 접근하는 스레드들은 대기하게 된다. 그리고 이후에 뮤텍스를 원래의 Signaled
   상태로 바꾸어 주는 ReleaseMutex() 함수를 사용함으로써 대기하고 있던 스레드가 다시 실행하게 되는 것이다.

 - 뮤텍스는 스레드가 여러 개 있더라도 자신이 소유한 스레드가 누구인지를 기억하고 있으며, Windows 운영체제는
   뮤텍스가 반환되지 않은 상태에서 스레드가 종료될 경우 그 뮤텍스를 강제적으로 Signaled 해줌으로써 이를
   대기하고 있던 스레드가 무한정 기다리는 일이 없도록 해준다.

 - 뮤텍스는 뮤텍스를 소유한 스레드를 기억하고 있음으로써 같은 스레드가 같은 뮤텍스를 중복 호출하더라도 데드락
   현상이 발생하기 않게 하고있다. 즉, 내부적으로 같은 스레드가 같은 뮤텍스를 소유하려 할 경우 뮤텍스의 내부적인
   카운트만을 증가시켜 주고 이 스레드에 대한 진입은 허용하여 주게 된다. 그리고 이 내부적인 카운트가 0으로
   내려갔을 경우에 Signaled 상태로 돌려줌으로써 다른 스레드에 대해서는 중복 호출한 스레드가 뮤텍스에 대한
   사용을 모두 종료한 후에 진입하도록 하고 있으며, 이러한 기능은 같은 스레드의 재귀 호출에 의한 데드락 현상을
   방지하여 주게 된다.


3. 이벤트(Event)란?

 - 이벤트는 어떠한 사건에 대하여 알리기 위한 용도로 사용되는 동기화 객체이다. 이벤트 객체의 경우 우리가
   Windows에서 메시지를 교환할 때 사용하는 개념과 같은 개념이다. 즉, Windows의 메시지 교환 방식은 이벤트에
   기반한 방식이라고 이야기한다. 키보드가 눌려질 경우 WM_KEYDOWN, 마우스 왼쪽 버튼이 눌러질 경우
   WM_LBUTTONDOWN과 같은 메시지가 날라오며, 이러한 신호는 이벤트를 통하여 통보하게 되는 것이다.

 - 이벤트의 경우 SetEvent() 또는 ResetEvent()를 사용하여 동기화 객체들의 상태를 마음대로 바꿀 수 있게 된다. 


4. 세마포어(Semaphore)란?

 - 세마포어는 사용자가 지정한 개수만큼 이 동기화 객체로 보호하는 자원에 대하여 접근할 수 있도록 하고 있다.
   즉, 세마포어에서는 사용 가능한 자원의 개수를 세팅할 수 있도록 하고 있으며, 그 값은 세마포어 초기화 시에
   세팅하게 된다.

 - 세마포어가 초기화되었을 때에는 뮤텍스와 마찬가지로 Signaled 상태로 되어 있으며, 세마포어의 자원이 하나
   사용될 때마다 사용 가능한 자원의 개수는 1씩 감소하게 된다. 그리고 이 개수 값이 1 이상일 때까지는 Signaled
   상태로 계속 유지되고 이 값이 0이 되면 세마포어의 상태는 NonSignaled가 되어 이 이후에 접근하는 스레드들에
   대하여 대기하도록 만들게 된다. 그리고 사용 가능한 자원의 개수가 다시 1 이상이 되면 세마포어의 상태가 다시
   Signaled 상태로 되어 대기하고 있던 스레드가 계속하여 세마포어의 자원을 사용할 수 있게 하는 것이다.

 - 세마포어의 자원에 대한 반환은 ReleaseSemaphore() 함수를 사용하며, 자신이 사용한 자원의 개수에 대하여
   lReleaseCount만큼 그 내부 카운터를 증가시키게 된다.

출처 : Windows 구조와 원리 그리고 Codes

Posted by 위너즈
|
error C2146: 구문 오류 : ';'이(가) ... 식별자 앞에 없습니다.
error C4430: 형식 지정자가 없습니다. int로 가정합니다. 참고: C++에서는 기본 int를 지원하지 않습니다.
error C4430: 형식 지정자가 없습니다. int로 가정합니다. 참고: C++에서는 기본 int를 지원하지 않습니다.

...

위와 같은 에러가 나는 이유는 클래스를 찾을 수 없는 경우에 발생합니다. 분명히 클래스가 있는데도 불구하고 이런 에러메시지가 발생하는 경우는.. 보통 교차포함을 한 경우에 이런 에러가 자주 발생합니다.
이게 무슨 얘기냐.. 다음을 보시죠..

b.h
#pragma once
#include "a.h"
class B
{
public:
 A a;
};

a.h
#pragma once
#include "b.h"
class A
{
public:
 B b;
};

양쪽의 클래스들은 서로를 필요로 하기 때문에 서로 #include을 해주었습니다.
언뜻 보기에는 문제가 없어보이죠. 실제로 자바에서는 에러가 나질 않습니다. 하지만 c++에서는 에러를 유발합니다. 무수히 많은 에러를 유발하죠.... 아주 많이....
 
하나하나 따라가보면 그 이유를 알 수 있습니다.
일단 b.cpp파일을 컴파일한다고 합시다. 그럼 b.cpp에는 최상단에 b.h가 include되어있을 겁니다. 그래서 컴파일러는 b.h를 포함시키죠. b.h를 가보니 상단에 a.h가 include되어있습니다. 그럼 그 헤더파일을 포함시키려 하겠죠. 그래서 a.h에 가보니.. 상단에 b.h가 include되어있습니다. 좀전에 b.cpp에서 b.h를 include했는데도 불구 한번더 include하려하지요.(아직 class B가 전부 읽혀진건 아닙니다.) 하지만 #pragma once구문 보이시죠? 이 구문때문에 헤더파일은 단 한번만 불려와지게 됩니다. 결국 a.h에 있는 #include "b.h"구문은 있으나 마나한 셈이 되죠. 그래서 class A의 B b부분에서 클래스 B는 이세상에 없는 클래스로 인식하고 형식이 없다는 에러메시지를 발생시키는 겁니다. 만약 class A에 포함된 에러 헤더파일 중 B를 필요로 하는 헤더파일이 있다면.. 에러메시지는 더욱더 많이 발생할 겁니다. 마찬가지로 a.cpp를 컴파일 하는경우 똑같은 에러가 나겠네요.

또한 서로 포함하지 않았는데도 불구, 이 에러메시지가 발생하는 경우가 있습니다.
그 경우는 서로는 포함하지 않았지만, 각 파일에 포함된 헤더파일들에 포함되어 간접적으로 서로를 포함한 경우가 해당됩니다.
b.h
#pragma once
#include "a.h"
class B
{
public:
 A a;
};

a.h
#pragma once
#include "c.h"
class A
{
public:
 B b;
};

c.h
#pragma once
#include "b.h"
class C
{
};


정말 간단하게 생각하면 #pragma once가 문제라고 생각하실 수 있습니다.
하지만 이걸 없애버리면 더 큰 문제가 발생합니다. class B가 두번 로드되는 경우죠. 심벌은 단 한개만 유효합니다. class B가 여러개 있을수는 없겠죠. 그렇다면, 단 한번만 불려와지고.. a.h에서도 인식할 수 있는 방법이 있느냐..? 물론 존재합니다. 여러가지 기법들이 존재하죠.



해결책

1. 가장 간단한 방법
헤더파일에서는 컴파일러에 단지 "암시"만 주고 포함시키지 않는 방법입니다.
b.h
#pragma once
class A; // class A가 존재한다고만 알려줍니다.
class B
{
public:
 A* a; // 포인터로 바꾸었습니다.
};

a.h
#pragma once
class B; // class B가 존재한다고만 알려줍니다.
class A
{
public:
 B* b;
};

※ 주의) 각각의 소스파일엔 포함시켜줘야합니다. 이렇게 하면 서로 include를 하지 않기 때문에 위와 같은 에러가 발생하지 않습니다. class A; 라고 하기만 하고 끝낸 부분이 눈에 띄는데, 이 부분은 실제로 클래스를 정의하진 않고 단지 앞으로 정의될 것이다, 나중에 링크과정때 찾아보라고 하는 일종의 암시입니다. 당장은 컴파일을 위해 때우는(?) 수단이라고 보시면 되겠죠. 그리고 A a에서 A* a로 포인터로 바뀐 부분을 알 수가 있는데, 일반 변수의 경우 크기를 알아야 하기 때문이죠. 따라서 일반 변수로 했다면 B를 컴파일 하는 도중 A의 크기를 구하려고 할 것이고, 에러를 유발하곤 합니다. 반면에 포인터 변수는 어떤 타입에도 상관없이 4바이트를 고수합니다.

한가지 주의하실 점은, 저렇게 하고 b.h에서 A의 멤버변수(함수)에 접근하는 인라인 함수같은 코드는 넣으시면 안됩니다. 컴파일 되는 당시로썬 A의 상세코드는 알길이 없기 때문이죠. 단 다음과 같은 경우는 가능합니다. 그 이유는 당장엔 A의 내용을 알필요가 없기 때문입니다. 소스파일에 넣으시기 바랍니다.
b.h
#pragma once
class A; // class A가 존재한다고만 알려줍니다.
class B
{
public:
 A* a; // 포인터로 바꾸었습니다.
 B() : a(NULL) {}
 ~B(){ if( a != NULL)delete a; } // 이 구문은 절대 안됩니다. 현재로썬 a의 크기를 알수 없기 때문입니다.
 A* GetAPtr() { return a; }
};




2. 좀더 나은 방법
b.h
#pragma once
#include "ABase.h"
#include "BBase.h"
class B : public BBase
{
public:
 B();
 virtual ~B();
 ABase* a;
};

a.h
#pragma once
#include "ABase.h"
#include "BBase.h"
class A : public ABase
{
public:
 A();
 virtual ~A();
 BBase* b;
};

b.cpp
#include "b.h"
#include "a.h"

B::B()
{
  a = new A();
}
B::~B()
{
  if( a!=NULL ) delete a;
}

BBase.h
class BBase
{
public:
  virtual ~BBase(){}
};

클래스를 상속으로 계층관계로 만들어버린 후, 부모클래스를 포함시키는 방법입니다. 정의는 부모클래스지만 당연히 할당은 자식클래스로 하게 되겠죠?^^; 이 방법은 실제로 자주 사용되고 있습니다. 유명한 패턴중 상태패턴에서도 이런 구조로 사용되죠. 그리고 컨테이너들도 저런 방식과 유사하게 설계되었을거라 생각합니다. 하지만, 무리하게 이 방식으로 할 필욘 없다고 생각합니다. 몇몇의 경우는 제외하고는 이 방식보단 처음방식이 더 나을수도 있겠습니다..^^



맺음말
실제로 이런 디자인은 말라고 합니다만.. 현재 라이브러리에서는 이런 디자인이 비일비재합니다. 가장 간단한 예로 MFC에서 부모와 차일드 윈도우 관계죠. 또는 게임 오브젝트 관리자와 게임 오브젝트들과 서로 포함시켜서 프로그래밍을 단순화 시키기도 합니다. 때로는 이런 디자인이 간편하고 가독성에도 일조한단 얘기죠.
저작자 표시 비영리 변경 금지
출처 : http://ekessy.tistory.com/trackback/20 
 

'Programming > C++' 카테고리의 다른 글

C/C++언어 함수들  (0) 2011.08.22
[C++] 레퍼런스(&) 미사용시 복사생성자의 무한루프  (0) 2011.05.18
Posted by 위너즈
|
opengl이나 다이렉트x에서 텍스트를 표시할때는 주로 글씨자체를 텍스쳐화 시켜서 표현하고는 합니다.

일반적으로 텍스트를 그냥 그리는것은 그자리에서 이미지를 만들고 렌더링을 하기때문에 속도도 느려지고

 어느부분은 지원을 안해주는곳도 있습니다. 여기서 이미지를 만들고 렌더링하는 부분을 따로 만드는것이

이번 테크닉의 핵심입니다. 물론 퍼포먼스 자체도 텍스쳐화 하는것이 더 좋습니다. 처음에 한번 이미지를 

만들고 나중엔 렌더링만 하기 때문이죠. 



클래스에서 다른부분은  제끼고 텍스쳐생성 부분만 설명하겠습니다. 다른부분은 조금만 공부해도

알수있는 부분입니다. 

public class Text3d {
 
 private IntBuffer   mVertexBuffer;
    private IntBuffer   mColorBuffer;
    private ByteBuffer  mIndexBuffer;
    private FloatBuffer mfTexBuffer;
    private int mTextureID;
   
 public Text3d(){
     int one = 50;
         int vertices[] = {
                 0, one, 0,
                 one, one, 0,
                 0,  0, 0,
                 one,  0, 0,
              
         };
        
         float tex[] = {
           0.0f ,0.0f,
           1.0f,0.0f,
           0.0f ,1.0f,
           1.0f,1.0f,
           
         };
         one = 100000;
         int colors[] = {
           one,    one,    one,  one,
                 one,    one,    one,  one,
                 one,  one,    one,  one,
                 one,  one,    one,  one,
               
         };
         byte indices[] = {
                 0, 1, 2,
                 1, 3, 2,
         };
    
         ByteBuffer vbb = ByteBuffer.allocateDirect(vertices.length*4);
         vbb.order(ByteOrder.nativeOrder());
         mVertexBuffer = vbb.asIntBuffer();
         mVertexBuffer.put(vertices);
         mVertexBuffer.position(0);
        
         ByteBuffer tbb = ByteBuffer.allocateDirect(tex.length*4);
         tbb.order(ByteOrder.nativeOrder());
         mfTexBuffer = tbb.asFloatBuffer();
         mfTexBuffer.put(tex);
         mfTexBuffer.position(0);
         ByteBuffer cbb = ByteBuffer.allocateDirect(colors.length*4);
         cbb.order(ByteOrder.nativeOrder());
         mColorBuffer = cbb.asIntBuffer();
         mColorBuffer.put(colors);
         mColorBuffer.position(0);
         mIndexBuffer = ByteBuffer.allocateDirect(indices.length);
         mIndexBuffer.put(indices);
         mIndexBuffer.position(0);
        
     
     }
 

  public void TexCreate(GL10 gl,Context mContext)
  {
   int[] textures = new int[1];
         gl.glGenTextures(1, textures, 0);
         mTextureID = textures[0];
         gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
        
         gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
                 GL10.GL_NEAREST);
         gl.glTexParameterf(GL10.GL_TEXTURE_2D,
                 GL10.GL_TEXTURE_MAG_FILTER,
                 GL10.GL_LINEAR);
         gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
                 GL10.GL_CLAMP_TO_EDGE);
         gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
                 GL10.GL_CLAMP_TO_EDGE);
         gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
                 GL10.GL_REPLACE);
        
       
        
      Bitmap mBitmap;
     
      Canvas mCanvas;
     
      Bitmap.Config config =   Bitmap.Config.ARGB_8888;
     
      mBitmap = Bitmap.createBitmap(128, 128, config);
         mCanvas = new Canvas(mBitmap);
         mBitmap.eraseColor(0);
        
        
         mCanvas.drawColor(0x00ffffff);
        
        
        
         Paint Pnt = new Paint();
         Pnt.setColor(0xff00ff00);
         Pnt.setTextSize(128);
         Pnt.setAntiAlias(false);
         Pnt.setTextScaleX(1);
        
         mCanvas.drawText("B", 0, 128, Pnt);
        
        
         GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, mBitmap, 0);
        
        
        
         mBitmap.recycle();   
        

   
  }
     public void draw(GL10 gl)
     {
      
         gl.glFrontFace(GL10.GL_CW);
         gl.glEnable(GL10.GL_TEXTURE_2D);
         gl.glColor4f(1f, 1f, 1f, 1f);
         gl.glTexEnvx(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
                 GL10.GL_MODULATE);
        
         gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
        
         gl.glEnableClientState(GL10.GL_VERTEX_ARRAY);
         gl.glEnableClientState(GL10.GL_TEXTURE_COORD_ARRAY);
         gl.glActiveTexture(GL10.GL_TEXTURE0);
       
                
       
         gl.glTexCoordPointer(2, GL10.GL_FLOAT, 0, mfTexBuffer);
         gl.glVertexPointer(3, GL10.GL_FIXED, 0, mVertexBuffer);
         gl.glColorPointer(4, GL10.GL_FIXED, 0, mColorBuffer);
         gl.glDrawElements(GL10.GL_TRIANGLES, 6, GL10.GL_UNSIGNED_BYTE, mIndexBuffer);
        
        
     }
}









위 클래스의 TexCreate함수를 가져왔습니다. 여기서 하나하나 설명 하겠습니다.

  public void TexCreate(GL10 gl,Context mContext)
  {

        여기는 텍스쳐를 생성하고 id에 연결하는 부분입니다. 그렇게 어렵지는 않습니다. 패스!
    
         int[] textures = new int[1];
         gl.glGenTextures(1, textures, 0);
         mTextureID = textures[0];
         gl.glBindTexture(GL10.GL_TEXTURE_2D, mTextureID);
        
         gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_MIN_FILTER,
                 GL10.GL_NEAREST);
         gl.glTexParameterf(GL10.GL_TEXTURE_2D,
                 GL10.GL_TEXTURE_MAG_FILTER,
                 GL10.GL_LINEAR);
         gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_S,
                 GL10.GL_CLAMP_TO_EDGE);
         gl.glTexParameterf(GL10.GL_TEXTURE_2D, GL10.GL_TEXTURE_WRAP_T,
                 GL10.GL_CLAMP_TO_EDGE);
         gl.glTexEnvf(GL10.GL_TEXTURE_ENV, GL10.GL_TEXTURE_ENV_MODE,
                 GL10.GL_REPLACE);
         
        
         

     여기서 부터가 핵심입니다.
   
      Bitmap mBitmap;         비트맵입니다
     
      Canvas mCanvas;      켄버스입니다.
     
      Bitmap.Config config =   Bitmap.Config.ARGB_8888;      비트맵을 설정해줍니다 ARGB_8888
      
      mBitmap = Bitmap.createBitmap(128, 128, config);         128x128 ARGB_8888 비트맵을 생성합니다
         mCanvas = new Canvas(mBitmap);                         비트맵으로 켄버스를 생성합니다. 켄버스에
                                                                                   그려지는 그림은 비트맵에 그려지게 됩니다.
                                                                                   비트맵은 2의 승수로 만드시길 추천합니다.
                                                                                   잘못하면 안나오는수가 있습니다.
        
         mBitmap.eraseColor(0);           비트맵을 지정색으로 지워줍니다
        
        
         mCanvas.drawColor(0x00ffffff);        켄버스에 드로우컬러를 설정해줍니다. 글씨로 그려지는
                                                            나머지 부분이 그려집니다. 투명하게 하고싶으면 알파값을
                                                            빼줍시다...         
         
         
         Paint Pnt = new Paint();                  페인트 객체를 생성합니다.

         Pnt.setColor(0xff00ff00);                  페인트의 색을 결정해 줍시다. 즉 글씨의 색이 됩니다. 지금은 녹색!

         Pnt.setTextSize(128);                     텍스트의 사이즈를 정해줍니다.128짜리 사이즈니까 꽉차게 되겠죠!
        
         Pnt.setAntiAlias(false);                   안티얼라이즈 취향에 맞게 선택해 줍시다.. true로 하면 조금 
                                                            부드러운 글씨가 나옵니다. 하지만 텍스트 사이즈가 작으면 작
                                                            으면 작을수록 형체를 알아보기 힘듭니다. 사이즈가 클때 추천!
                                 
         Pnt.setTextScaleX(1);                     장평을 설정해줍니다. 1이니까 그대로 나옵니다.
        
         mCanvas.drawText("B", 0, 128, Pnt);     드디어 대망에 그리기입니다! 비트맵에 B가 찍혀서 나옵니다.
                                                                 여기서 원하시는 단어나 문장을 입력하시면 되겠죠.. 
                                                                 지금은 텍스쳐에 글씨를 꽉 차게 그립니다. 문장을 쓰시려면
                                                                 텍스트 사이즈를 작게 잡거나 비트맵을 크게 잡으셔야 합니다.
         
         
         GLUtils.texImage2D(GL10.GL_TEXTURE_2D, 0, mBitmap, 0);   비트맵을 텍스쳐로 보내줍니다..
        
        
        
         mBitmap.recycle();    비트맵을 해재시켜줍니다...
         

   
  }


이제 만들어진 텍스쳐를 위에 draw함수처럼 폴리곤에 적용만 시켜주면 화면에 B가 찍혀나오는것을 

 볼수있습니다. 테크닉 자체가 3d를 쓰려면 필수이긴하지만 어느정도 난이도가 있는 테크닉입니다.
Posted by 위너즈
|