[LNK2019] inet_addr 사용 오류

error LNK2019: __imp__inet_addr@4 외부 기호(참조 위치: "int __stdcall License(struct HWND__ *,unsigned int,unsigned int,long)" (?License@@YGHPAUHWND__@@IIJ@Z) 함수)에서 확인하지 못했습니다.



라이브러리 추가 안해서 생긴 오류

 #pragma comment(lib, "Ws2_32") 

추가하여 해결 


LNK2019 에러 났을 경우 라이브러리 확인해보기!


* 특히 디버그 했을때는 실행 됐는데,

릴리즈 일때 실행 되지 않았을 경우 릴리즈에서 라이브러리 추가 안됐을 확률이 높다 




LINK : fatal error LNK1104: 'libboost_regex-vc100-mt-gd-1_51.lib' 파일을 열 수 없습니다.






라이브러리 경로를 추가 안해줘서 생기는 오류!!


저 위치에 라이브러리 위치 추가하기 

'and so on > error' 카테고리의 다른 글

버그. 에러, 예외  (0) 2013.01.25
F5 실행 Ctrl F5 결과 값 차이 발생  (0) 2012.12.07
[SVN] checkout 하기  (0) 2012.12.04
[LNK2001] 외부 기호를 확인할 수 없습니다.  (0) 2012.11.26
[LNK2019] inet_addr 사용 오류  (0) 2012.10.18

C++ DLL 함수 char*를 C#에서 읽어 오기

- C++에서 만든 dll 함수 


extern "C" __declspec(dllexport) char* Suma(char* a, char*b)

{

char* result = (char*)LocalAlloc(LPTR, strlen(a) + strlen(b) +1);

strcat(result, a);

strcat(result, b);

  LocalFree(result);

return result;

}






- C#에서 dll함수 적용하기

class Program

{


 [DllImport("C:\\DllName.dll", CallingConvention = CallingConvention.Cdecl)]

public static extern System.IntPtr Suma(string a, string b);


static void Main()

{

string a = "a";

string b = "b";

IntPtr p = Suma(a,b);

string c = Marshal.PtrToStringAnsi(p);

Marshal.FreeHGlobal(p);

Console.WriteLine(c);

}

}




C++ 에서는 

LocalAlloc을 이용 메모리 할당 해줘야 함


C#에서는

 IntPtr 구조체를 선언하여 dll 함수 저장 후 

Marshal.PtrToStringAnsi() 메소드 이용하여 관리되는 string,  관리되지 않는 ANSI 문자열 복사 

Marshal.FreeHGlobal() 메소드 이용하여 할당한 메모리 해제 






 출처 - http://blog.naver.com/PostView.nhn?blogId=nickpooh&logNo=50108296076&redirect=Dlog&widgetTypeCall=true

RegAsm

C#으로 만든 프로그램을 


dll로 만들때 RegAsm.exe을 사용하려고 검색 했는데


regasm a.dll /tlb:a.tlb 


이 명령어를 쓰면 된다길래 열심히 cmd에서 두드렸지 ㅋㅋㅋㅋ 


근데 그게 아니고 


C:\ProgramData\Microsoft\Windows\Start Menu\Programs\Microsoft Visual Studio 2010\Visual Studio Tools


여기에 있는 Visual Studio 명령 프롬프트에서 써야 하는 것이었다 흑흑  


 

C# - Excel 내용 읽어오기

Excel 내용을 읽는 것을 하고 있는데

Excel. range범위를


range = ESheet.get_Range("A1", missing); //A1 셀 선택 

range = range.get_Resize(5,5) // A1부터 5,5의 크기 


이런 식으로 설정 해줘야 해서.

이런 식으로는 텍스트를 읽어 올 수 있는데 

내가 모든 EXCEL 파일의 셀의 크기를 알 수 없어서 

읽어 오는 파일 마다 셀의 크기가 다른데 그럴 땐 어떻게 해야 하나 

하루 종일 찾았다 ㅜㅜ


(엑셀에서 셀이 만들어 질 수 있는 크기까지 찾아서 모든 크기안에 있는 내용을 찾으려고 했는데

데이터가 너무 커서 오버플로우 남 ㅋ  1048576 x 16384)


셀에 대한 메서드가 따로 있어서 

range를 설정 해 줄때 사용된 범위에 있는 마지막 셀을 이용하여 

아무 엑셀 파일을 선택하면 텍스트를 읽어 올 수 있게 설정해 주었다.


      public string ReadExcel(string path)

        {

           string filename = path;// string filename = "C:\\test.xlsx";

            object missing = System.Reflection.Missing.Value;


            Excel.Application EApp = new Excel.Application();


            Excel.Workbook EBook;

            Excel.Workbooks EBooks;


            Excel.Sheets ESheets;

            Excel._Worksheet ESheet;


            Excel.Range range;


            EApp.Visible = false;

//          EApp.WindowState = Excel.XlWindowState.xlMinimized;


            EBooks = EApp.Workbooks;

            EBook = EApp.Workbooks.Open(filename, missing, missing, missing, missing, missing, missing

               , missing, missing, missing, missing, missing, missing, missing, missing);

            

            ESheets = EBook.Worksheets;

            ESheet = (Excel._Worksheet)EBook.ActiveSheet;

            ESheet = (Excel._Worksheet)ESheets.get_Item(1);


            range = ESheet.get_Range("A1").SpecialCells(Excel.XlCellType.xlCellTypeLastCell);


           long row = range.Row;

            long column = range.Column;

            

String valueString = "";


            for (long rowCounter = 1; rowCounter <= row; rowCounter++)

            {

                for (long colCounter = 1; colCounter <= column; colCounter++)

                {

                    Excel.Range cell = (Excel.Range)ESheet.Cells[rowCounter, colCounter];


                    if (cell.Value == null)

                        valueString = string.Concat(valueString, " ");

                    else

                    {

                        valueString = string.Concat(valueString, cell.Value.ToString() + ",");

                        Console.Write(valueString);

                    }

                        textBox1.Text = valueString;


                }

                valueString = String.Concat(valueString,"\r\n");


            }




================================================================================
저 위의 함수를 이용해서 그동안 엑셀을 읽어 왔는데, 
데이터가 너무 클 경우에는 읽는 속도가 10분이 넘어감...ㅋㅋ( 2중 for문 때문인가ㅜㅜ )

그래서 새로운 방법을 알아 냄 
DataTable을 이용하여서 DataTable에 값을 저장 -> 이 부분이 진짜 빠름

나는 필요한게 String 형이여서 row[Col].ToString()으로 변환 해준다 

그래도 이전보다는 빨라졌당 1분 30초 정도 


using System.Data.OleDb;


      public string ReadExcel(string strFilePath)
        {
            // 엑셀 문서 내용 추출
            object missing = System.Reflection.Missing.Value;
            String valueString = "";

            string strProvider = string.Empty;
            strProvider = "Provider=Microsoft.ACE.OLEDB.12.0; Data Source=" + strFilePath + @";Extended Properties=Excel 12.0";

            OleDbConnection excelConnection = new OleDbConnection(strProvider);
            excelConnection.Open();

            string strQuery = "SELECT * FROM [Sheet1$]";

            OleDbCommand dbCommand = new OleDbCommand(strQuery, excelConnection);
            OleDbDataAdapter dataAdapter = new OleDbDataAdapter(dbCommand);

            DataTable dTable = new DataTable();
            dataAdapter.Fill(dTable);

            // dTable에 추출된 내용을 String으로 변환
            foreach (DataRow row in dTable.Rows)
            {
                foreach (DataColumn Col in dTable.Columns)
                {
                    valueString += row[Col].ToString() + " ";
                }
            }
        
            dTable.Dispose();
            dataAdapter.Dispose();
            dbCommand.Dispose();

            excelConnection.Close();
            excelConnection.Dispose();

            return valueString;
        }







- 참고 

NamedRange.SpecialCells 메서드

셀에 대한 내용
http://technet.microsoft.com/ko-kr/subscriptions/microsoft.office.tools.excel.namedrange.specialcells

C# - Excel 창 접근하기

Application -> Books -> Book -> Sheets -> Sheet  순으로 설정 





        private void button1_Click(object sender, EventArgs e)

        {

            string filename = "C:\\test.xlsx";

            object missing = System.Reflection.Missing.Value;


            Excel.Application EApp;

            Excel.Workbook EBook; 


            Excel.Workbooks EBooks;

            Excel.Sheets ESheets;

            Excel._Worksheet ESheet;


            EApp = new Excel.Application();

            EApp.Visible = false;


            EBooks = EApp.Workbooks;

            EBook = EApp.Workbooks.Open(filename, missing, missing, missing, missing, missing, missing

                , missing, missing, missing, missing, missing, missing, missing, missing);

            ESheets = EBook.Worksheets;

            ESheet = (Excel._Worksheet)ESheets.get_Item(1);


//         Range 설정 해줘야 함 

.

.

.

.

.

.

.

.

.

.

.

.

.

.

//아래 적어주면 지금 작업중인(filename에 해당하는) 엑셀 창이 뜬다.


                EApp.Visible = true;

                EApp.UserControl = true;



}

C# - 파일 선택 다이얼로그 띄우기





            OpenFileDialog ofd = new OpenFileDialog();


            ofd.Filter = "모든 파일 (*.*) | *.*";

            ofd.ShowDialog();


            string path = ofd.FileName;

            textPathName.Text = ofd.FileName;



1. ofd.Filter에는 다이얼로그 창에 나오는 파일 종류 선택 할 수 있다  

예를들어 MS워드파일만 다이얼로그 창에 나오게 하고 싶으면 

ofd.Filter =  "WodrDocuments(*.doc) | *.doc";


2. textPathName은 내가 도구상자에서 만들어 준 textBox 이름 이어서 

textPathName.Text 하여 string을 지정할 경우 해당하는 string이 textbox에 표시된다.  


아이디어가 고갈되었을 때의 처방전 20

아이디어가 고갈되었을 때의 처방전 20
1. 무의식을 활용하라
2, 종이에 적어라
3. 스케치북은 항상 필수
4, 한 걸음 떨어지는 것도 괜찮다
5. 시작한 것들을 먼저 마무리하라
6. 스튜디오의 분위기를 밝게 하라
7. 이전의 사례를 그대로 답습하지 말라
8. 예상하지 못할 만한 것들을 기대하라
9. 그럴싸하지 않아 보이는 곳이 노다지일 수 있다.
10. 마음의 지경을 넓혀라
11. 다른 크리에이티브 분야를 모색하라
12. 수동적인 흐름에 젖지 말라
13. 개인 시간을 가져라
14. 메모하는 습관이 중요하다
15. 의뢰 내용에 너무 얽매이지 않는다
16. 스스로의 지평선을 확장하라
17. 한계란 뛰어 넘으라고 있는 것이다.
18. 새로운 시각을 모색하라
19. 주변 환경에 변화를 주어라
작업 환경에 살짝 변화를 주는 것만으로도 생각이 전환된다. 사무실을 벗어나, 침대에서 잠옷 차림으로 스케치를 한다든지, 전철 안에서 작업을 시도해본다. 아니면 팀원들과 카페에서 브레인 스토밍을 하는 것도 좋은 방법이다.
20. 잠은 충분히 자도록 한다.
아이디어를 떠올렸다고 그날 바로 작품을 완성시킬 수는 없다. 또한 그렇게 해서도 안 된다. 사람이란 본능적으로 좋은 것과 나쁜 것을 구분하도록 되어 있기 때문에, 아이디어를 떠올린 후 잠을 자는 동안 그 아이디어에 대한 새로운 판단을 할 수 있게 된다. 아이디어도 숙성되어야 한다.

 

작업 디렉터리

파일을 열때나 dll로 작업할때

파일경로를 지정하지 않고 파일 이름만 쓰고 싶은 경우가 있다.

 

그런 경우 그 파일을 어느 디렉토리에 저장해야 파일 이름만 적어도 프로젝트가 파일을 열 수 있을까?

 

나는 그 프로젝트와 관련된 폴더에 다 넣었었다ㅋㅋ

디버그 폴더에도 넣고, 프로젝트 폴더에도 넣고 어느 폴더 중 하나만 걸려라 하는 마음에ㅋㅋ

 

프로젝트 속성 페이지만 가도 알 수 있는데

 

ALT + F7을 눌러 ( [프로젝트] - [속성])

프로젝트 속성 페이지에 들어가

 

 

 

구성 속성 -> 디버깅 메뉴에 들어가면

작업 디렉터리가 있다.

여기서 보면 $(ProjectDir)로 표시되어 있을 건데

그 위치에서 파일을 가져 오는 것 같다.

 

이 ProjectDir의 위치를 알고 싶으면

옆에 ▼를 눌러 <편집....>을 선택하여

뜨는 창에서 매크로(M) 버튼을 눌러 확인하면 된다. 

 

값을 설정하지 않더라도 위치를 확인 할 수 있다

 

 

 

문자열 처리함수 정리(멀티바이트 -> 유니코드)

멀티 바이트 환경에서 사용하던 함수를 유니코드 환경에서 사용하려고 하면 사용이 안된다.

처음에 VS2008을 사용하면서 예전 책을 보면서 공부할 때 가장 많이 머리가 아프던 문제였다.

유니코드 환경에서 사용 할 수 있게 정의가 되어진 함수들은 같은 함수명을 써도 자동으로 처리가 되기 때문에

특별히 신경을 쓸 일은 없었다. 그러나 문자열처리 함수 같은경우는 아예 함수 이름이 바뀌었기 때문에 모른다면 사용 할 수가 없다.

그래서 문자열 처리 함수를 정리 할 겸 유니코드 환경에서 사용 할 수 있는 문자열 처리 함수를 정리해 보았다.

일단 기본적으로 멀티 바이트 환경에서 문자열 처리 함수의 접두어는 str 이었다 strlen, strcat, strstr 등등

그러나 유니코드 환경에서 접두어는 wcs이다. 이것만 기억해 둔다면 이미 문자열처리 함수의 절반은 안것이다.


1-1.strcpy -> wcscpy

:문자열을 복사하는 함수이다

원형 :

wchar_t *wcscpy(
wchar_t *strDestination, 복사 당하는 대상
const wchar_t *strSource 복사 하려는 소스
);

ex)

TCHAR str[256];

wcscpy(str,L"안녕하세요");

TextOut(hdc,0,0,str,wcslen(str));

:결과 = 0,0에 "안녕하세요" 문자열 출력



1-2. strncpy -> wcsncpy

:입력한 사이즈 만큼 문자열을 복사하는 함수이다

원형 :

wchar_t *wcsncpy(
wchar_t *strDest, 복사 당하는 대상
const wchar_t *strSource, 박사 하려는 소스
size_t count 복사하려는 개수
);

ex)

TCHAR str[256];

memset(str,0,sizeof(str)); NULL값으로 배열을 초기화

wcsncpy(str,L"안녕하세요", 2);

TextOut(hdc,0,0,str,wcslen(str));

:결과 = 0,0에 "안녕" 문자열 출력


2. strlen -> wcslen

: 입력 받은 문자열의 길이를 반환해준다.

sizeof와 다른점은 sizeof는 배열의 전체크기를 반환해주고

wcslen은 중간에 NULL을 만나면 NULL까지의 길이만 반환한다.

원형 :

size_t wcslen(
const wchar_t *str
);


3-1.strcat -> wcscat

: 두 문자열을 이어준다

원형 :

wchar_t *wcscat(
wchar_t *strDestination,
const wchar_t *strSource
);

ex)

wcscpy(str,L"안녕하세요");
wcscat(str,L"오냐");

TextOut(hdc,0,0,str,wcslen(str));

:결과 = 0,0에 "안녕하세요오냐" 출력


3-2.strncat -> wcsncat

: 입력한 사이즈만큼 대상에 소스를 이어준다

원형 :

wchar_t *wcsncat(
wchar_t *strDest,
const wchar_t *strSource,
size_t count
);

ex)

wcscpy(str,L"안녕하세요");
wcsncat(str,L"오냐",1);

TextOut(hdc,0,0,str,wcslen(str));

:결과 = 0,0에 "안녕하세요오" 출력


4-1.strcmp -> wcscmp

:대소문자를 구분하지 않고 문자열을 비교한다.

원형 :

int wcscmp(
const wchar_t *string1,
const wchar_t *string2
);

string1string2가 같으면 0

string1>string2 이면 양수

string1<string2 이면 음수

ex)

wcscpy(str,L"안녕하세요");

wcscpy(str2,L"하이");

if(wcscmp(str,str2) == 0){

TextOut(hdc,0,0,L"같다",2);

}else{

TextOut(hdc,0,0,L"다르다",3);

}

:출력 = 0,0에 "다르다" 출력


4-2.strncmp -> wcsncmp

:지정한 사이즈만큼 대소문자를 구분하지 않고 문자열을 비교한다.

원형 :

int wcsncmp(
const wchar_t *string1,
const wchar_t *string2,
size_t count
);

string1string2가 같으면 0

string1>string2 이면 양수

string1<string2 이면 음수

ex)

wcscpy(str,L"안녕하세요");

wcscpy(str2,L"안하이");

if(wcsncmp(str,str2,1) == 0){

TextOut(hdc,0,0,L"같다",2);

}else{

TextOut(hdc,0,0,L"다르다",3);

}

:출력 = 0,0에 "같다" 출력



5-1. stricmp -> wcsicmp

:대소문자를 구별하지 않고 문자열을 비교

원형 :

int _wcsicmp(
const wchar_t *string1,
const wchar_t *string2
);

string1string2가 같으면 0

string1>string2 이면 양수

string1<string2 이면 음수

ex)

wcscpy(str,L"ABCDE");

wcscpy(str2,L"abcde");

if(wcsicmp(str,str2) == 0){

TextOut(hdc,0,0,L"같다",2);

}else{

TextOut(hdc,0,0,L"다르다",3);

}

:출력 = 0,0에 "같다" 출력



5-2. strnicmp -> wcsnicmp

:대소문자를 구별하지 않고 문자열을 비교

원형 :

int _wcsnicmp(
const wchar_t *string1,
const wchar_t *string2,
size_t count
);

string1string2가 같으면 0

string1>string2 이면 양수

string1<string2 이면 음수

ex)

wcscpy(str,L"ABCDE");

wcscpy(str2,L"abcdefgh");

if(wcsnicmp(str,str2,5) == 0){

TextOut(hdc,0,0,L"같다",2);

}else{

TextOut(hdc,0,0,L"다르다",3);

}

:출력 = 0,0에 "같다" 출력



6-1.strchr -> wcschr

:문자열에서 한 문자를 찾아 그 문자가 있는 주소를 반환하여 준다. (문자열의 처음부터 검사한다)

:만약에 찾지 못했을 경우에는 NULL값을 반환해준다

원형:

wchar_t *wcschr(
wchar_t *str,
wchar_t c
);

ex)

wcscpy(str2,L"에요안녕하세요하이");

TCHAR dd = L'요';
TCHAR * ddd;

ddd = wcschr(str2,dd);

TextOut(hdc,0,0,ddd,wcslen(ddd));

:출력 = 0,0에 "요안녕하세요하이" 출력



6-2.strrchr -> wcsrchr

:문자열에서 한 문자를 찾아 그 문자가 있는 주소를 반환하여 준다. (문자열의 맨 마지막부터 검색한다)

:만약에 찾지 못했을 경우에는 NULL값을 반환해준다

원형:

wchar_t *wcsrchr(
wchar_t *str,
wchar_t c
); // C++ only

ex)

wcscpy(str2,L"에요안녕하세요하이");

TCHAR dd = L'요';
TCHAR * ddd;

ddd = wcsrchr(str2,dd);

TextOut(hdc,0,0,ddd,wcslen(ddd));

:출력 = 0,0에 "요하이" 출력



7.strstr -> wcsstr

:문자열에서 원하는 문자열을 찾아준다.

원형 :

wchar_t *wcsstr(
wchar_t *str,
const wchar_t *strSearch
);

ex)

wcscpy(str2,L"에요안녕하세요하이");

TCHAR * ddd;
ddd = wcsstr(str2,L"안녕");

TextOut(hdc,0,0,ddd,wcslen(ddd));

:출력 = "안녕하세요하이" 출력


8.strpbrk -> wcspbrk

: 첫번째 인수로 받은 문자열에서 두번째 인수로 받은 문자열중 한문자라도 빨리 나오는 문자의 주소를 반환해준다.

원형 :

wchar_t *wcspbrk(
wchar_t *str,
const wchar_t *strCharSet
); // C++ only

ex)

wcscpy(str2,L"에요안녕하세요하이");

TCHAR * ddd;

ddd = wcspbrk(str2,L"녕세"); '녕' 이나 '세' 이 두글자 중에 빨리 나오는 문자의 주소를 출력해준다

TextOut(hdc,0,0,ddd,wcslen(ddd));

:출력 = "녕하세요하이" 출력



9.strtok -> wcstok

: 첫번째 매개변수로 받은 문자열을 두번째 매개변수로 받은 토큰 문자로 나누어준다.

원형 :

wchar_t *wcstok(
wchar_t *strToken,
const wchar_t *strDelimit
);

ex)

wcscpy(str2,L"나의'가치'는 내가 결정하고, 당신의 '가치'는 당신이 결정한다");
TCHAR * ddd;

ddd = wcstok(str2,L" ,'"); //토큰은 여러개를 지정할 수 있다. 여기서는 공백(' ')과 콤마(',') 작은따옴표(')로 지정했다.
while(ddd != NULL){
TextOut(hdc,0,i,ddd,wcslen(ddd));
ddd = wcstok(NULL,L" ,'"); //검색을 계속 해야하기 때문에 NULL값을 매개변수로 넣어준다

i+=20;
}



wcstok의 방식은 문자열에서 처음 토큰을 발견하면 그 주소를 저장하고 두번째 토큰을 찾아내면 그 토큰을 NULL로 만들고

처음 토큰 주소를 반환해준다. 또한 wcstok함수는 함수 중간 결과를 자체적으로 정적변수를 사용하고 있다. 그렇기 때문에

계속 검색을 하고 싶으면 첫번째 매개변수로 NULL을 넣어주면 문자열이 끝날때 까지 검색을 한다.

검색이 끝나면 NULL을 반환해 준다.

wcstok함수도 매개변수로 받은 데이터를 손상시키기 때문에 데이터가 손상되지 않게 하려면 다른곳에 복사한 후에 써야한다.

또한 함수 자체적으로 정적 변수를 사용하고있기 때문에 멀티 스레드 환경에서 동시에 호출될 염려가 있으므로

동시에 호출되지 않도록 보호해 주어야 한다.

:출력 =

나의

가치

내가

결정하고

당신의

가치

당신이

결정한다



10-1.strset -> wcsset

: 첫번째 매개변수로 받은 문자열을 NULL문자 전까지 모두 두번째 문자로 바꾼다

원형 :

wchar_t *_wcsset(
wchar_t *str,
wchar_t c
);

ex)

wcscpy(str,L"ABCDE");

wcsset(str,L'd');
TextOut(hdc,0,0,str,wcslen(str));

:출력 = 0,0에 "ddddd" 문자열이 출력된다



10-2.strnset -> wcsnset

: 첫번째 매개변수로 받은 문자열을 입력받은 사이즈 만큼 두번째 문자로 바꾼다

원형 :

wchar_t *_wcsnset(
wchar_t *str,
wchar_t c,
size_t count
);

ex)

wcscpy(str,L"ABCDE");

wcsnset(str,L'd',2);
TextOut(hdc,0,0,str,wcslen(str));

:출력 = 0,0에 "ddCBD" 문자열이 출력된다



11.

strupr -> wcspur

strlwr -> wcslwr

: 지정한 문자열을 대문자로 치환(wcspur) 하거나 소문자로 치환(wcslwr)한다.

: 단 대문자나 소문자만 치환이 되고 한글이나 숫자는 치환되지 않는다.

: 이 함수도 매개변수로 받은 문자열을 변형시키기 때문에 변형되어서는 안되는 문자열이면 복사를 해놓고 사용해야 한다.

wcscpy(str,L"1abcdeABCDE아");

wcsupr(str);
TextOut(hdc,0,0,str,wcslen(str));

wcslwr(str);
TextOut(hdc,0,20,str,wcslen(str));

:출력 =

0,0에 "1ABCDEABCDE아" 출력

0,20에 "1abcdeabcde아" 출력

12.strrev -> wcsrev

: 지정한 문자열을 역순으로 배치한다. 한글도 역순으로 배치된다.

: 이 함수도 매개변수로 받은 문자열을 변형시키기 때문에 변형되어서는 안되는 문자열이면 복사를 해놓고 사용해야 한다.

원형 :

wchar_t *_wcsrev(
wchar_t *str
);

ex)

wcscpy(str,L"1abcdeABCDE아");

wcscpy(str2,L"나의 '가치'는 내가 결정하고, 당신의 '가치'는 당신이 결정한다");

wcsrev(str);
wcsrev(str2);

TextOut(hdc,0,0,str2,wcslen(str2));
TextOut(hdc,0,20,str,wcslen(str));

:출력 =

0,0에 "다한정결 이신당 는'치가' 의신당 ,고하정결 가내 는'치가' 의나" 출력

0,20에 "아EDCBAedcba1" 출력