성태의 닷넷 이야기
홈 주인
모아 놓은 자료
프로그래밍
질문/답변
사용자 관리
사용자
메뉴
아티클
외부 아티클
유용한 코드
온라인 기능
MathJax 입력기
최근 덧글
[정성태] 아쉽게도, 커뮤니티는 아니고 개인 블로그입니다. ^^
[정성태] 질문이 잘 이해가 안 됩니다. 우선, 해당 소스코드에서 ILis...
[양승조
] var대신 dinamic으로 선언해서 해결은 했습니다. 맞는 해...
[양승조
] 또 막혔습니다. ㅠㅠ var list = props[i].Ge...
[양승조
] 아. 감사합니다. 어제는 안됐던것 같은데....정신을 차려야겠네...
[정성태] "props[i].GetValue(props[i])" 코드에서 ...
[정성태] 저렇게 조각 코드 말고, 실제로 재현이 되는 예제 프로젝트를 압...
[정성태] Modules 창(Ctrl+Shift+U)을 띄워서, 해당 Op...
[정성태] 만드실 수 있습니다. 단지, Unity 엔진 내의 스크립트와 W...
[공진영] 안녕하세요 좋은글 감사합니다. 현재 제가 wpf로 관제 모...
글쓰기
제목
이름
암호
전자우편
HTML
홈페이지
유형
제니퍼 .NET
닷넷
COM 개체 관련
스크립트
VC++
VS.NET IDE
Windows
Team Foundation Server
디버깅 기술
오류 유형
개발 환경 구성
웹
기타
Linux
Java
DDK
Math
Phone
Graphics
사물인터넷
부모글 보이기/감추기
내용
<div style='display: inline'> <br /> <div style='font-family: 맑은 고딕, Consolas; font-size: 20pt; color: #006699; text-align: center; font-weight: bold'>XmlCodeGenerator를 C/C++ 코드 생성에 적용</div><br /> <br /> XmlCodeGenerator에 대해서는 가끔씩 설명을 드렸지요. (개인적으로, 사실 엄청 잘 쓰고 있는 자작 툴입니다. ^^)<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > XML/XSLT로 구현하는 매크로 확장 ; <a target='_tab' href='/2/0/542'>http://www.sysnet.pe.kr/2/0/542</a> XmlCodeGenerator 1.0.0.4 업데이트 ; <a target='_tab' href='/2/0/760'>http://www.sysnet.pe.kr/2/0/760</a> </pre> <br /> 아쉬운 점이 하나 있다면, 이런 CodeGenerator 사용자 정의 툴이 Managed 언어를 다루는 프로젝트에서만 적용된다는 점입니다. 굳이 이런 제한을 둘 필요가 있었을까 싶지요!<br /> <br /> 오늘은, 문득 이에 대한 해결책이 생각났습니다.<br /> <br /> 간단합니다. 코드 생성하는 파일들은 그냥 C# 프로젝트에 넣어버리고, C++ 프로젝트에서는 상대 경로를 include하는 것으로 해당 코드들을 그냥 포함해 버리는 것입니다. 이렇게 되면, 심지어 소스 컨트롤을 연결해서 관리하는 것에도 문제가 없습니다. 실제로 한번 따라해 볼까요? ^^<br /> <br /> <hr style='width: 50%' /><br /> <br /> <div style='font-family: 맑은 고딕, Consolas; font-size: 12pt; color: #2211AA; text-align: left; font-weight: bold'>1. XML 파일 생성</div><br /> <br /> 자신의 코드에서 복잡하게/반복적으로 사용되는 코드를 간단하게 관리할 수 있는 XML 파일을 만듭니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > <?xml version="1.0" encoding="utf-8" ?> <people> <person name="Tester" age="15" /> <person name="Administrator" age="17" /> </people> </pre> <br /> <div style='font-family: 맑은 고딕, Consolas; font-size: 12pt; color: #2211AA; text-align: left; font-weight: bold'>2. XSLT 파일 생성</div><br /> <br /> XML 파일의 내용을 C/C++ 코드로 만들어 줄 XSLT 파일을 만듭니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > <?xml version="1.0" encoding="utf-8"?> <xsl:stylesheet version="1.0" xmlns:xsl="http://www.w3.org/1999/XSL/Transform" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:msxsl="urn:schemas-microsoft-com:xslt" xmlns:xcg="http://www.sysnet.pe.kr/WPFClassMemberDef" > <xsl:param name="XCG_CurrentTime"/> <xsl:output method="text" encoding="utf-8" indent="yes"></xsl:output> <xsl:template match="people"> /* Created: <xsl:value-of select="$XCG_CurrentTime" /> */ #if defined (HEADER_DECLARATION) #if !defined __CPP_ARRAY_H #define __CPP_ARRAY_H typedef struct tagPerson { wstring Name; int Age; } Person; extern vector <xsl:text disable-output-escaping="yes">&lt;</xsl:text>Person *<xsl:text disable-output-escaping="yes">&gt;</xsl:text> g_people; void InitializePeople(); #endif #endif #if defined (IMPLEMENTATION_DEFINITION) vector <xsl:text disable-output-escaping="yes">&lt;</xsl:text>Person *<xsl:text disable-output-escaping="yes">&gt;</xsl:text> g_people; void InitializePeople() { <xsl:for-each select="person"> { Person *pItem = new Person(); pItem-<xsl:text disable-output-escaping="yes">&gt;</xsl:text>Name = L"<xsl:value-of select="@name" />"; pItem-<xsl:text disable-output-escaping="yes">&gt;</xsl:text>Age = <xsl:value-of select="@age" />; g_people.push_back(pItem); } </xsl:for-each> } #endif </xsl:template> </xsl:stylesheet> </pre> <br /> <div style='font-family: 맑은 고딕, Consolas; font-size: 12pt; color: #2211AA; text-align: left; font-weight: bold'>3. XmlCodeGenerator 적용</div><br /> <br /> 생성한 XML 파일과 XSLT 파일을 C# 프로젝트에 추가하고, XML 파일의 "Custom Tool" 속성을 "XmlCodeGenerator"로 지정해 줍니다.<br /> <br /> [그림 1: XmlCodeGenerator 적용]<br /> <img alt='cpp_xmlcodegen_1.png' src='/SysWebRes/bbs/cpp_xmlcodegen_1.png' /><br /> <br /> 그러면, "그림 1"에서 보는 것처럼 XML 파일 하위에 .cs 파일이 생성됩니다. CS 파일의 내용은 C/C++에서 사용될 수 있는 코드로 다음과 같이 생성됩니다.<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > /* Created: 09/13/2009 21:19:05 */ <b style='COLOR: blue'>#if defined (HEADER_DECLARATION)</b> #if !defined __CPP_ARRAY_H #define __CPP_ARRAY_H typedef struct tagPerson { wstring Name; int Age; } Person; extern vector <Person *> g_people; void InitializePeople(); #endif <b style='COLOR: blue'>#endif</b> <b style='COLOR: blue'>#if defined (IMPLEMENTATION_DEFINITION)</b> vector <Person *> g_people; void InitializePeople() { { Person *pItem = new Person(); pItem->Name = L"Tester"; pItem->Age = 15; g_people.push_back(pItem); } { Person *pItem = new Person(); pItem->Name = L"Administrator"; pItem->Age = 17; g_people.push_back(pItem); } } <b style='COLOR: blue'>#endif</b> </pre> <br /> 매크로 상수를 이용해서 하나의 CS 파일 안에 C/C++ 헤더 파일과 코드에서 사용될 수 있도록 하고 있습니다.<br /> <br /> C# 프로젝트에서는 위의 CS 파일이 빌드되면 오류가 발생하기 때문에 CS 파일에 대해서는 컴파일 옵션을 "None"으로 해줍니다.<br /> <br /> [그림 2: Build Action - None 적용]<br /> <img alt='cpp_xmlcodegen_2.png' src='/SysWebRes/bbs/cpp_xmlcodegen_2.png' /><br /> <br /> <div style='font-family: 맑은 고딕, Consolas; font-size: 12pt; color: #2211AA; text-align: left; font-weight: bold'>4. 생성된 CS 파일을 C/C++ 프로젝트에서 사용</div><br /> <br /> 이제, C/C++ 프로젝트에서 #include를 이용해서 해당 파일들을 포함시켜 줍니다. 간단하게는 stdafx.h/stdafx.cpp 파일에서 각각 다음과 같이 추가시켜주면 되겠지요. ^^<br /> <br /> <pre style='margin: 10px 0px 10px 10px; padding: 10px 0px 10px 10px; width: 800px; background-color: #fbedbb; overflow-x: scroll; font-family: Consolas, Verdana;' > ======== stdafx.h ========== #pragma once #include "targetver.h" #include <stdio.h> #include <tchar.h> #include <string> #include <vector> using namespace std; #define HEADER_DECLARATION #include "..\CppTestCodeGenerator\CppArray.cs" ======== stdafx.cpp ======== #include "stdafx.h" #undef HEADER_DECLARATION #define IMPLEMENTATION_DEFINITION #include "..\CppTestCodeGenerator\CppArray.cs" </pre> <br /> <hr style='width: 50%' /><br /> <br /> 이제부터는 Person이라는 코드를 관리하기 위해 C/C++ 코드를 찾아가서 수정할 필요 없이 해당 XML 파일을 수정함으로써 편리하게 코드에 결과를 반영할 수 있습니다. 위에서는 단순하게 예를 들었지만, 복잡하게/반복적으로 초기화되는 코드를 위의 자동 생성 코드로 치환해 두면 자칫 실수할 수 있는 오류 횟수를 많이 줄일 수 있습니다.<br /> <br /> 사실... 시간이 지났을 때, C/C++ 코드를 다시 보면서 코드를 추가하는 것보다 XML로 추가하는 것이 더욱 직관적이죠. 초보적인 수준이긴 하지만 이것도 DSL(Domain Specific Language)이라고 할 수 있지 않을까요!<br /> <br /> <a target='_tab' href='http://www.sysnet.pe.kr/bbs/DownloadAttachment.aspx?fid=486&boardid=331301885'>첨부된 파일은 위의 예제를 테스트한 프로젝트</a>입니다.<br /> <br /><br /><hr /><span style='color: Maroon'>[이 토픽에 대해서 여러분들과 의견을 공유하고 싶습니다. 틀리거나 미흡한 부분 또는 의문 사항이 있으시면 언제든 댓글 남겨주십시오.]</span> </div>
첨부파일
스팸 방지용 인증 번호
2032
(왼쪽의 숫자를 입력해야 합니다.)