블로그 이미지
Every unexpected event is a path to learning for you. blueasa

카테고리

분류 전체보기 (2861)
Unity3D (899)
Programming (479)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (192)
협업 (65)
3DS Max (3)
Game (12)
Utility (142)
Etc (99)
Link (34)
Portfolio (19)
Subject (90)
iOS,OSX (53)
Android (16)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (19)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday

string str = @"E:\JAVA\Sample\X509Test\minMain.java.bak";

            System.Diagnostics.Debug.WriteLine("경로명:" + System.IO.Path.GetDirectoryName(str));
            System.Diagnostics.Debug.WriteLine("확장자:" + System.IO.Path.GetExtension(str));
            System.Diagnostics.Debug.WriteLine("파일명:" + System.IO.Path.GetFileName(str));

            System.Diagnostics.Debug.WriteLine("분리자:" + System.IO.Path.AltDirectorySeparatorChar);
            System.Diagnostics.Debug.WriteLine("확장자유무:" + System.IO.Path.HasExtension(str).ToString());
            System.Diagnostics.Debug.WriteLine("순파일명:" + System.IO.Path.GetFileNameWithoutExtension(str));
            System.Diagnostics.Debug.WriteLine("root:" + System.IO.Path.GetPathRoot(str));
            System.Diagnostics.Debug.WriteLine("랜덤파일명:" + System.IO.Path.GetRandomFileName());
            System.Diagnostics.Debug.WriteLine("임시파일:" + System.IO.Path.GetTempFileName());
            System.Diagnostics.Debug.WriteLine("임시경로:" + System.IO.Path.GetTempPath());

 

            //---------------------------------------------------------------------------
            int n= str.LastIndexOf(@"\");
            System.Diagnostics.Debug.WriteLine("파일명:" + str.Substring(0, n));
            System.Diagnostics.Debug.WriteLine("경로명:" + str.Substring(n + 1, str.Length - n - 1));

반응형
Posted by blueasa
, |
예제 XML 파일 
1.<!--?xml version="1.0" ?-->     <myapp>        <welcome>Welcome to MyApp</welcome>        <farewell>Thank you for using MyApp</farewell>              <windows>         <windowname="MainFrame" w="400" h="250"y="15" x="5">       </window></windows>       <connectiontimeout="123.456000"ip="192.168.0.1">       </connection></myapp>

파일에서 읽을때
1.TiXmlDocument document;        document.LoadFile(_File_Name_);

문자열로 읽을때
1.TiXmlDocument document;        document.Parse(szXML);

Node와 Element를 가져올때
1.TiXmlElement* pRoot = document.FirstChildElement("MyApp");        if( NULL == pRoot ) return FALSE;        char* szRootName = pRoot->Value(); //Value()를 사용하면 Node의 이름을 알수있다

각 태그의 속성값 읽어올때 
여기에선 위예제의 windows 태그의 속성을 읽어본다.
1.TiXmlElement* pElement = pRoot->FirstChildElement("Windows");        char* szName = pElement->Attribute("name");         char* szX = pElement->->Attribute("x");         char* szY = pElement->->Attribute("y");         char* szW = pElement->->Attribute("w");         char* szH = pElement->->Attribute("h");

정수형으로 읽고 싶으면~
1.int x;pElement->Attribute("x", &x);

모든 속성값을 한번에 읽어올때
1.TiXmlElement* pElement = pRoot->FirstChildElement("Windows");          TiXmlAttribute* attrib = pElement ->FirstAttribute(); //pElement의 속성을 받아온다.     while(attrib)   {           const char* szAttribute = attrib->Value();             attrib = attrib->Next();         }

Child Node를 순회 할때
1.TiXmlElement* pRoot = doc.RootElement();        TiXmlElement* pChild;        for(pChild = pRoot ->FirstChildElement() ; pChild != 0 ; pChild = pChild->NextSiblingElement())        { //Node를 돌면서..        }

Save XML 
Xml 형식선언할때
1.TiXmlDocument doc;   TiXmlElement* msg; TiXmlDeclaration* decl = newTiXmlDeclaration( "1.0""""" );   doc.LinkEndChild( decl );      //결과값 : <!--?xml version="1.0" ?-->

서브 노드를 추가할때
1.TiXmlElement * root = new TiXmlElement( "MyApp" );   doc.LinkEndChild( root );

주석문장을 추가할때
1.TiXmlComment * comment = new TiXmlComment();comment->SetValue(" Settings for MyApp " );  root->LinkEndChild( comment );

Message 서브노드와 하위 노드및 데이터를 추가할때
1.TiXmlElement * msgs = new TiXmlElement( "Messages" );       root->LinkEndChild( msgs );       msg = new TiXmlElement( "Welcome");       msg->LinkEndChild( new TiXmlText( "Welcome to MyApp"));       msgs->LinkEndChild( msg );       msg = new TiXmlElement("Farewell" );       msg->LinkEndChild( new TiXmlText( "Thank you for using MyApp" ));       msgs->LinkEndChild( msg );

노드를 추가하고 Attribute를 설정할때 레벨을 맞추기 위해서 root의 하위로 추가 한것을 주의 깊게 봐야 한다.
1.TiXmlElement * windows = new TiXmlElement( "Windows" );       root->LinkEndChild( windows );       TiXmlElement * window;     window =new TiXmlElement( "Window" );       windows->LinkEndChild( window );       window->SetAttribute("name""MainFrame");     window->SetAttribute("x", 5);     window->SetAttribute("y", 15);     window->SetAttribute("w", 400);     window->SetAttribute("h", 250);

Double 값 (소수점 값) 을 설정할때
1.TiXmlElement * cxn = new TiXmlElement( "Connection" );       root->LinkEndChild( cxn );       cxn->SetAttribute("ip","192.168.0.1");     cxn->SetDoubleAttribute("timeout", 123.456); // floating point attrib

Xml파일로 저장할때
1.// 파일로 저장      doc.SaveFile("text.xml");     //문자열로..     TiXmlPrinter printer;     printer.SetStreamPrinting();     Doc.Accept( &printer );      char* pAA = printer.CStr();                    // char* 를 반환한다.     std::string str = printer.Str();                  // std::string으로 반환한다.

반응형

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

TinyXML Read  (2) 2010.12.08
TinyXML Write  (0) 2010.12.08
XML introduce(XML 문법 설명)  (0) 2010.04.27
Tiny XML 링크  (0) 2010.04.27
Posted by blueasa
, |

TinyXML Read

Programming/TinyXML / 2010. 12. 8. 14:43

C++용 XML 라이브러리가 몇가지 있다. MSXML 라이브러리, TinyXML 라이브러리가 있다.
작고 빠르다고 알려진 TinyXML 라비브러리를 알아 본다.

내가 사용한 버전은 TinyXML 2.5.3 버전이다. xmltet.cpp는 메모장에서 파일 인코딩을
UTF-8로 열고 유니코드 인코딩으로 재 저장하여 문자가 깨지지 않도록 한다.

TinyXML의 NodeType

TinyXml의 NodeType은 XML의 노드 타입과 대부분 비슷 하다.
XML 서적이나 문서를 보면 주석, 속성, TEXT, Element들의 최소단위는 노드이다. 
엘리먼트와 노드를 혼동하지 않도록 한다. 
TinyXML에서는 TiXmlElement노드가 TiXmlNode를 상속하고 있다.  

COMMENT 노드: 주석을 표현 하는 노드

ELEMENT 노드: 엘리먼트를 표현 하는 노이다.
              Test.xml에서는 root, food, name, country가 엘리먼트이다.
              (test.xml 파일은 아래에 나온다.)

TEXT 노드: 트리 구조상 최말단 노드로 문자 데이터를 표현하는 노드이다.

Attribute node: TinyXml 노드 타입에는 존재하지 않지만 TinyXml에서는 속성을 얻어                 올수 있는 메소드를 제공한다.

나머지 node 타입은 문서를 참고한다.

 

헤더 파일 포함

TinyXML 내부에서 자체 string 클래스 대신 std::string 클래스를 사용 할려면,
TIXML_USE_STL을 선언한다.
STL 사용에 필요한 헤더를 포함 시킨다.

#define TIXML_USE_STL    // TinyXML의 string대신 std::string을 사용할 경우.

#include “tinyxml.h”

 

#ifdef TIXML_USE_STL

    #include <iostream>

    #include <sstream>

    using namespace std;

#else

    #include <stdio.h>

#endif

 

라이브러리 링크

TIXML_USE_STL에 따라 라이브러리 링크를 다르게 설정한다.

//lib 파일 링크

 

#ifdef TIXML_USE_STL

 

#ifdef _DEBUG

#pragma comment(lib, "tinyxmld_STL")

#else

#pragma comment(lib, "tinyxml_STL")

#endif

 

#else

 

#ifdef _DEBUG

#pragma comment(lib, "tinyxmld")

#else

#pragma comment(lib, "tinyxml")

#endif

 

#endif

test.xml

읽을려는 XML 파일이다.

<?xml version="1.0" encoding="euc-kr"?>

<root>

  <!--각국의 대표 음식들이다.-->

  <food num="1">

      <name>김치</name>

      <country>대한민국</country>

  </food>

  <food num="2">

    <name>햄버그</name>

    <country>미국</country>

  </food> 

</root>

파일을 통해 읽을려면

    TiXmlDocument doc;

    doc.LoadFile("test.xml");

문자열을 통해 읽을려면

    TiXmlDocument doc;

    doc.Parse(szXML);

root 엘리먼트 노드를 읽는다.

TiXmlElement* rootElement = doc.FirstChildElement( "root" );

"root"의 자식 "food" 엘리먼트 노드를 읽는다.

    TiXmlElement*  element = doc.FirstChildElement( "root" )->FirstChildElement("food");

"food" 엘리먼트 노드를 반복해서 출력 한다.

    1     while( element )

    2     {

    3         //Value()는 현재 Node의 문자열을 넘겨준다.

    4         //GetText()는 현재 Text 타입 Node의 문자열을 넘겨 준다.

    5         //element->FirstChildElement()->Value()는 "name"을 넘겨준다.

    6         const char* num = element->Attribute( "num" );

    7         std::cout << "num Attribute: " << num << std::endl;

    8         std::cout << "name: " << element->FirstChildElement("name")->GetText() << std::endl;

    9         std::cout << "country: " << element->FirstChildElement("country")->GetText() << std::endl;

   10         element = element->NextSiblingElement( "food" );

   11     }

1: "food" 엘리먼트가 있을 때 까지 반복한다.

6: "num" 속성의 문자열을 읽어 온다.

속성을 정수로 읽을려면 다음과 같이 한다.
TiXmlAttribute* attr = element->FirstAttribute();
int n = attr->IntValue();

7: "name" 엘리먼트의 값을 읽는다.

8: "country" 엘리먼트의 값을 읽는다.

10: 다음 "food" 엘리먼트로 이동 한다.

 

XML 전체 파싱

ShowXML()은 XML을 파싱하여 보여주는 함수이다.
코드 설명은 생략....

void ShowXml(TiXmlNode *pNode)

{

       if(pNode)

       {

              switch(pNode->Type())

              {

              case TiXmlNode::COMMENT:

                    std::cout << "COMMENT: " << pNode->Value() << std::endl;

                    break;

              case TiXmlNode::DECLARATION:

                    std::cout << "DECLARATION: " << std::endl;

                    break;

 

              case TiXmlNode::ELEMENT:

                  {

                      std::cout << "ELEMENT: [" << pNode->ToElement()->Value() << "]" << std::endl;

                      TiXmlAttribute *pAttr = pNode->ToElement()->FirstAttribute();

                      while(pAttr)

                      {

                         std::cout << pAttr->Name() << "=\"" << pAttr->Value() << "\"" << std::endl;

                         pAttr = pAttr->Next();

                      }

                  }

                  break;

 

              case TiXmlNode::TEXT:

                   TiXmlText* pText = pNode->ToText();

                   if(pText)

                       std::cout << "TEXT:  " << pText->Value() << std::endl;

                   break;

              }

 

              for(TiXmlNode *pNext = pNode->FirstChild(); pNext; pNext = pNext->NextSibling())                     ShowXml(pNext);

       }

}

소스

tinyxml.zip

참조:

http://hanburn.tistory.com/7

http://hanburn.tistory.com/8


출처 : http://dolphin.ivyro.net/file/algorithm/etc/tinyXml_read.html

반응형

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

TinyXml 사용법 요약  (0) 2010.12.08
TinyXML Write  (0) 2010.12.08
XML introduce(XML 문법 설명)  (0) 2010.04.27
Tiny XML 링크  (0) 2010.04.27
Posted by blueasa
, |

TinyXML Write

Programming/TinyXML / 2010. 12. 8. 14:36

TinyXML Read의 test.xml과 같은 포맷으로 XML 파일을 저장해 보자.
저장될 파일은 다음과 같다.

test_write.xml

<?xml version="1.0" encoding="euc-kr" ?>

<root>

    <!--각국의 대표 음식들이다.-->

    <food num="1">

        <name>김치</name>

        <country>대한민국</country>

    </food>

</root>

XML 형식 선언

TiXmlDocument doc; 

TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "euc-kr", "" ); 

doc.LinkEndChild( decl );

우리나라 문자셋의 1.0 버전이 만들어 진다.

서브 노드 추가

TiXmlElement * root = new TiXmlElement( "root" ); 

doc.LinkEndChild( root );

"root" 엘리먼트를 추가한다. TinyXML에서 노드를 추가 할 때, new로 생성한 엘리먼트는
내부에서 자동으로 삭제 되기 때문에 해제 할 필요가 없다.

주석 추가

TiXmlComment * comment = new TiXmlComment();

comment->SetValue( "각국의 대표 음식들이다." ); 

root->LinkEndChild( comment );

root의 자식으로 "food" 서브 노드 추가

TiXmlElement *food = new TiXmlElement( "food" ); 

root->LinkEndChild( food );

root의 자식이 되는 "food" 서브 노드를 추가한다.

food의 Attribute로 "num" 추가

food->SetAttribute("num", 1);   //food->SetAttribute("num", "1")와 동일

food->SetAttribute( "num", "1" )도 동일한 결과이다.

food의 자식으로 name 서브 노드와 값 추가

TiXmlElement *name = new TiXmlElement( "name" ); 

food->LinkEndChild( name ); 

name->LinkEndChild( new TiXmlText( "김치" ));

food의 자식 노드로 "name"을 추가하고 값은 "김치"이다.

food의 자식 노드로 country 서브 노드와 값 추가

TiXmlElement *country = new TiXmlElement( "country" ); 

food->LinkEndChild( country ); 

country->LinkEndChild( new TiXmlText( "대한민국" ));

food의 자식 노드로 "country"를 추가하고 값은 "대한민국"이다.

저장 하기

doc.SaveFile("test_write.xml");

SaveFile()을 통해 원하는 파일명으로 값을 저장한다.

전체 소스

void WriteXml()

{

    //형식 선언

    TiXmlDocument doc; 

    TiXmlDeclaration* decl = new TiXmlDeclaration( "1.0", "euc-kr", "" ); 

    doc.LinkEndChild( decl );

 

    //서브 노드 추가

    TiXmlElement * root = new TiXmlElement( "root" ); 

    doc.LinkEndChild( root ); 

 

    //주석 추가

    TiXmlComment * comment = new TiXmlComment();

    comment->SetValue( "각국의 대표 음식들이다." ); 

    root->LinkEndChild( comment ); 

 

    //root의 자식으로 food 서브 노드 추가

    TiXmlElement *food = new TiXmlElement( "food" ); 

    root->LinkEndChild( food ); 

 

    //food의 Attribute로 "num" 추가

    food->SetAttribute("num", 1);   //food->SetAttribute("num", "1")와 동일

 

    //food의 자식으로 name 서브 노드와 값 추가

    TiXmlElement *name = new TiXmlElement( "name" ); 

    food->LinkEndChild( name ); 

    name->LinkEndChild( new TiXmlText( "김치" ));

 

    //food의 자식으로 country 서브 노드와 값 추가

    TiXmlElement *country = new TiXmlElement( "country" ); 

    food->LinkEndChild( country ); 

    country->LinkEndChild( new TiXmlText( "대한민국" ));

 

    doc.SaveFile("test_write.xml");

}

콘솔 창으로 XML 파일 보여주기

void PrintXml()

{

    TiXmlDocument doc( "test.xml" );

    doc.LoadFile();

 

    //문자열로..

    TiXmlPrinter printer;

    printer.SetStreamPrinting();

    doc.Accept( &printer );

    const char* pStr = printer.CStr();        // char* 를 반환한다.

    printf( pStr );

#ifdef  TIXML_USE_STL

    const std::string str = printer.Str();    // std::string으로 반환한다.

#endif

}

XML 파일을 콘솔 창으로 보여준다...

소스:

tinyxml.zip

참조:

http://hanburn.tistory.com/7

http://hanburn.tistory.com/8


출처 : http://dolphin.ivyro.net/file/algorithm/etc/tinyXml_write.html

http://dolphin.ivyro.net/file/algorithm/etc/tinyXml_write.html

반응형

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

TinyXml 사용법 요약  (0) 2010.12.08
TinyXML Read  (2) 2010.12.08
XML introduce(XML 문법 설명)  (0) 2010.04.27
Tiny XML 링크  (0) 2010.04.27
Posted by blueasa
, |
반응형
Posted by blueasa
, |
배포시에는 Dependency Walker(depends.exe)와 같은 도구를 사용하여 종속 DLL의 목록을 확인한다. 또한 2005이상의 VS(Visual Studio)는 manifest를 꼭 확인해서 사용한 dll과 버전을 확인해야한다. 

VC++ Library
그림 1(VS2005 기준)

그림은 VS2005를 기준으로 하고 있지만 다른 버젼도 위와 같은 규칙으로 명명되고 있다. xx는 각각의 버전을 나타내며 플랫폼 별로 x86,ia64,x64용이 따로 있다. u는 Unicode버전을 나타내고 m은 managed code를 사용했을때 사용되며 배포시 .NET Framework이 필요하다. 배포폴더에 manifest가 존재하면 같이 배포한다.

참고
Visual C++ Libraries as Shared Side-by-Side Assemblies - MSDN

64-bit 모드(IA64, X64)에 관해서


컴파일러와 라이브러리의 버젼을 나타내는 매크로

Predefined Macros - MSDN

_MSC_VER(MS 컴파일러)

  Visual Studio 4.0  1000
  Visual Studio 5.0  1100
  Visual Studio 6.0  1200
  Visual Studio .NET 2002  1300
  Visual Studio .NET 2003  1310
  Visual Studio 2005  1400
  Visual Studio 2008  1500

_MFC_VER(MFC 버젼)

 Visual Studio 6.0   0x0600
 Visual Studio .NET 2002   0x0700
 Visual Studio .NET 2003  0x0710
 Visual Studio 2005  0x0800
 Visual Studio 2008  0x0900

_ATL_VER(ATL 버젼)

 Visual Studio 6.0   0x0300
 Visual Studio .NET 2002   0x0700
 Visual Studio .NET 2003  0x0710
 Visual Studio 2005  0x0800
 Visual Studio 2008  0x0900


VC 6 이하(~ VS6)
VC6관련 DLL은 98이후부터는 운영체제에 포함되어 있다. 그러므로 현재는 배포시에 거의 문제될게 없다.

참고
ActiveX 배포를 위한 cab파일(MS) - inf파일에 링크를 추가해준다.
Vcredist.exe로 Visual C++ 응용 프로그램용 최신 런타임 구성 요소가 설치된다 - MSDN고객지원

VC 7.1(VS 2003)
VC7.1관련 DLL은 최신 운영체제라고 해서 더는 기본 내장을 해주지않기 때문에 응용 프로그램이 알아서 자기 디렉터리나 윈도우 시스템 디렉터리에다 구비해야 한다.

 vcredist_x86_2003.zip


VC 8이후(VS 2005~) 

Side by Side Asembly
2005부터는 side by side asembly라는 기술이 도입되어 VC관련 라이브러리들이 Windows 디렉토리 밑에 WinSxS (Windows Side-by-Side)라는 공유 폴더(native assembly cache)로 관리된다. side by side asembly는 DLL 충돌문제를 해결해서 각각의 어플리케이션에게 독립적인 DLL환경을 제공하기 위한것으로 여러버젼의 DLL들이 등록될수 있다. 복잡한 이과정을 간단하게 해결하는 방법으로 VC8부터는 재배포 패키지(Redistributable Package)라는 배포용 설치파일이 도입되어 공용 라이브러리를 자동으로 설치/등록해준다. 또한 프로젝트에서 자동 생성해주는 Manifest Flie에 사용된 DLL과 버전이 자동으로 입력되니 배포시는 꼭 확인하도록 한다. 
프로그래머나 사용자입장에선 관련 DLL을 포함만 하면 되는 기존 작업과 달리 설치파일이 하나 더생겼으니 귀찮은 작업이지만 최신 운영체제의 기본 관리 방법이기도 하고 .Net의 기술과도 무관하니 지금 정리하도록 하자.


최신 라이브러리를 Manifest에 기술하기(VC9)
배포방법을 알아보기 전에 알아두어야 할사항이 있다. VC9는 VC8과 달리 sp1같은 최신 라이브러리를 개발자PC에 설치했다고 해도 프로젝트가 최신라이브러리를 사용한다고 명시해주지 않으면 기존라이브러리를 기본으로 사용하므로 주의해야한다. 이것은 개발자가 sp1을 설치했어도 프로젝트는 기존 DLL버전을 사용하므로 배포시 sp1용 재배포 패키지를 사용하면 제대로 실행될 수 없음을 나타낸다. 방법은 아래와 같다.

'_BIND_TO_CURRENT_VCLIBS_VERSION'를 프로젝트 설정에서 선언해준다.
-> stdafx.h의 상단에 #define으로 입력해도 일반적인 프로젝트에선 상관없지만 프리컴파일드 헤더를 사용안하거나 외부라이브러리가 프로젝트에 미리 세팅되었을 경우 두개의 버전을 중복 사용하는 경우가 발생할 수 있으므로 프로젝트 설정에서 선언하길 권장한다. 이값은 CRT,MFC,ATL,OPENMP 4개의 '_BIND_TO_CURRENT...' 선언을 다 쓰겠다고 선언하는것이고 _BIND_TO_CURRENT_VCLIBS_VERSION의 기본값은 0으로 세팅되어있다.

Manifest File(2008 기준)


참고

응용 프로그램 재배포 및 특정 라이브러리에 바인딩 - MSDN

최신 라이브러리를 메니페스트에 기술하기


배포방법
그림1과 참고에 MSDN링크가 2005의 공용DLL 목록과 설명이다. side by side asembly로 인해 배포문제가 좀 복잡해져서 depends 만을 확인해서 관련 DLL을 포함한다고 제대로 실행된다는 보장을 받을 수 없게되었다. 일반적인 방법과 재배포 패키지를 사용하는 방법을 알아보자.

1. 정적 라이브러리(Static Library)를 사용한다.
실행파일이 커지긴 하나 제일 간단하다. MFC 라이브러리를 사용시는 MFC라이브러리를 정적으로 포함하면 CRT도 자동으로 /MT로 변경된다. 용량은 기본 MFC 다이얼로그 프로젝트가 52k정도에서 308k 정도로 커진다.
ATL과 OPENMP까지 사용한다면 웹에서 배포되는 ActiveX 같은 상황이면 용량때문에 고민해봐야할 문제이고 정적라이브러리도 동적라이브러리와 똑같다고는 하지만 몇가지 버그가 있으므로 주의하자.

참고
MFC Static으로 소켓사용시..

2. Manifest를 참조해서 기본 DLL을 배포한다.(Private Assembly)
배포방법이 바뀌었다곤 하나 관련 DLL을 포함해서 배포할수도 있다. VS의 설치폴더에 있는 공용DLL(Private Assembly)을 같이 배포하면 된다. 우선 Manifest로 사용한 DLL을 확인한후 "..\Microsoft Visual Studio X\VC\redist\"에서 관련 DLL(그림1참고)을 프로젝트 폴더에 포함한다. 이방법도 쉬운편이긴 하나 3MB정도의 크기인 재배포 패키지에 비하면 사용하는 라이브러리가 많을 수록 용량이 너무 큰편이다.(기본 CRT와 MFC라이브러리만 4.76MB - 2008sp1 기준)

3. 인스톨쉴드(Install Shield), 설치 프로젝트를 이용해서 재배포 패키지가 자동으로 설치되게 한다.
 -> 모든 프로젝트를 이렇게 만들긴 좀 귀찮다;;

4. .Net Framework(최신)를 설치한다.
.Net Framework를 설치하면 CRT관련 DLL만 같이 설치된다.(fx 3.5설치시 8.0과 9.0이 같이 설치됨)
managed로 컴파일했다면 .Net Framework는 필수이므로 고민할 문제가 아니지만 용량이 100메가도 훨씬 넘는다..;;

5. 재배포 패키지 - 아래에서 따로 설명한다.

위 방법 외에도 몇가지가 더 있으며 아래링크를 참조하기 바란다. 
RedistributingVisualCppRunTimeLibrary
Bootstrapper for the VC++ 2005 Redists (with MSI 3.1) - codeproject

재배포 패키지(Redistributable Package)
재배포 패키지는 Windows Installer 3.1을 필요로 하는 인스톨 파일이다. 한번 실행하기만 하면 자동으로 설치되지만 사용자 입장에선 불편한 사항이다. 하지만 Windows Installer의 Command line을 이용해서 몰래설치하는 방법이 있다. 이를 이용해서 런처형식의 프로그램을 만들면 Windows Installer 3.1의 설치유무와 재 배포 패키지 자동 설치를 하고 프로그램을 실행하게 할 수 있다. 좀더 범용적으로 사용하면 파일로 설치필요 설정값을 받아와서 COM관련 등록이나 웹배포시 ActiveX등록등을 자동으로 하게 만들수도 있다. 관련 소스가 정리되는 대로 블로그에 올리도록 하고 우선 VC6으로 재배포 패키지의 설치유무와 자동 실행하기 위한 코드를 설명하겠다.

1) 재배포 패키지 설치 유무 확인
재배포 패키지는 설치폴더에서 받거나(..\Microsoft Visual Studio X\SDK\v2.0\BootStrapper\Packages\vcredist_x86) 아래 링크를 통해 MS의 다운로드에서 받는다. 

2-1) 일반 적인 인스톨러 사용처럼 추가/제거 목록에 표시되므로 레지스트리 값으로 확인할 수 있다.
"HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\ProductCode"

2-2) MsiQueryProductState API를 이용해서 확인한다.
리턴값으로 INSTALLSTATE_DEFAULT인지만 확인하면 설치유무를 판단할 수 있다.

위 2개의 방법에서 모두 필요한 ProductCode는 아래와 같다.

Visual C++ 2005 runtime files

Visual C++ 2005 SP1 runtime files

Visual C++ 2008 runtime files

Visual C++ 2008 SP1 runtime files

위코드는 영문 버전이고 한글버전은 다르고 설치시 중복될수 있다. ProductCode와 추가/제거에 표시되는 이름외에 다른점은 없다. 참고로 2008 sp1 x86 한글버전은 {887868A2-D6DE-3255-AA92-AA0B5A59B874}이다.
Window7에서도 테스트 했음.

참고
How to detect the presence of the VC 8.0 runtime redistributable package
How to detect the presence of the Visual C++ 9.0 runtime redistributable package
NSIS로 VC8.0 Redistributables 체크방법
MsiQueryProductState를 통한 VC 2005 Redistribute 라이브러리 설치체크 방법


2) 재배포 패키지 몰래 설치하기(Command Line)
명령행으로 실행시 Windows Installer 로 만들어진 패키지는 /?로 명령어 종류를 볼수 잇다.

Windows Installer V3.0.1.4001.5512 기준으로 캡쳐한화면


VS2005
VC2005의 경우는 재배포 패키지가 VS기본 폴더에 존재하는 설치파일과 웹에서 받은 파일이 좀 다른데 웹에서 받은 재배포 패키지의 경우 압축이 한번더 되어있어서 인자값 설정 방법이 다르다. 또한 압축이 몇번에 걸쳐 되어있으므로 한글로 계정이 되어있어 한글 경로가 있을 경우 잘 설치가 안될수도 있다. 필자는 2008을 사용하므로 2005에 대한 사항은 관련 링크로 정확한 정보를 얻자.
How to perform a silent install of the Visual C++ 8.0 runtime files (vcredist) packages 
- VS기본 폴더에 포함된 재배포 패키지 설치
VC 8.0 런타임 (vcredist) 패키지 몰래 인스톨하기 - 웹에서 받은 재배포 패키지 설치(번역)
Visual C++ 2005 재배포 패키지가 설치안될때



VS2008
2008에서는 
<full path>\vcredist_x86.exe /qb
<full path>\vcredist_x86.exe /qb!
<full path>\vcredist_x86.exe /q   -> 화면에 전혀 보이지 않음
위 3가지 방법중 선택해서 사용하면 되며 Vista이상의 경우는 /q로 설정해도 UAC가 보이므로 필자는 /qb!를 사용한다. 직접 사용해보고 판단하자.

참고
How to perform a silent install of the Visual C++ 2008 redistributable packages

99%'s Code
위 재배포 패키지 몰래설치하기 코드를 간단하게 정리했음.

1. 설치유무 판단후 재배포 패키지를 설치하고 원하는 파일을 실행한다.
01. // 2008 sp1
02.    CString csProduct = "{887868A2-D6DE-3255-AA92-AA0B5A59B874}";  
03.//{9A25302D-30C0-39D9-BD6F-21E6EC160475}
04. 
05.    INSTALLSTATE t = MsiQueryProductState(csProduct);
06.    if(INSTALLSTATE_DEFAULT != t)
07.    {
08.        AfxMessageBox("재배포 패키지를 설치하겠습니다.");
09. //    WinExec("vcredist_sp1_x86.exe /q",SW_SHOW);
10.        WinExec("vcredist_sp1_x86.exe /qb!",SW_SHOW);
11.        AfxMessageBox("설치 완료");
12. // xp에선 설치완료후 정확하게 뜨지만 Windows7에선 완료되지 않았는데 뜬다.
13.    }
14.    else
15.        AfxMessageBox("이미 설치됨");
16.    
17.    // 아래 레지스트리값의 유무로 판단할수도 있다.(win7에서도 똑같다.)
18.    //HKEY_LOCAL_MACHINE\SOFTWARE\Microsoft\Windows\CurrentVersion\Uninstall\{887868A2-D6DE-3255-AA92-AA0B5A59B874}
19.    
20.    while(INSTALLSTATE_DEFAULT != MsiQueryProductState(csProduct))
21.        Sleep(30);
22.    WinExec("test.exe",SW_SHOW);    // 원하는 프로그램 실행

2. 제거
    WinExec("vcredist_sp1_x86.exe /qu",SW_SHOW);
    AfxMessageBox("제거 완료");

 
반응형
Posted by blueasa
, |

기본적으로 C#에서는 C++의 디폴트 매개변수 방법을 지원하지 않는 것 같다.

 

void func(int a, int b=1 ){ ... }

 

이런 함수가 있을 떄 디폴트 매개변수를 지원 안하면 같은 소스더라도 2배가 되기 때문에

 

디폴트 매개변수를 지정하는 것이 편할 때가 많았다.

 

하지만  C#에서는 지원을 따로 안하기 때문에 새로운 방법을 써야 한다.

 

public void func(int a){ func(a, 1); }

public void func(int a, int b){ ... }

 

이렇게 디폴트 파라미터가 필요없는 부분의 오버로딩시켜서 새로 호출 시키는 방법을 사용한다.

 

함수에 리턴값이 있을 경우는...

 

public int func(int a){ return func(a, 1); }

public int func(int a, int b){ ... }

반응형
Posted by blueasa
, |

IME 소스 (한글)

Programming/C/C++ / 2010. 11. 26. 21:58



ime 뭉탱이(module)  날읽어(README) ver 0.01

                     안노라군.
                 TEAM TRINITY.
             http://anoa.wo.to 
             kjm37@hanmail.net
//---------------------------------------------------------------------
적은 허접한 맨트와.. 버그있는 소스로 ime 강좌(같지도 않은)를 써서 
초보 IMER (ime + er)분 들을 나락의 길(?)로 빠트렸던 anoa 군입니다.;

아직도 몇몇 군데의 웹페이지들에 그 글들이 있길래. 너무도 죄송한(이라고 
쓰고 쪽팔린 이라고 읽는다.) 마음에.. 최종버전 소스를 정리해서 올립니다.


이번엔 강좌대신 상세한 주석(이라고 쓰고 게으름이라고 읽는다)으로 때웁니다.


          2003. 2. 16.
           class 청소부.  아노아군.

//---------------------------------------------------------------------
 소스
//---------------------------------------------------------------------
 프로젝트  : vc.net (vc 7.0) 
 마지막 업데이트 : 2003 년 2월 17일.
 소스의 기능  : IME 입력 및.. 특수문자(한자)의 목록 얻어내기.
      커서 기능 추가. (멀티라인은 지원하지 않습니다.)
 프로젝트구성 : ime
      +- BASE
       +- Error.h  // 에러 메세지용 헤더
       +- Main.cpp  // WinMain 및 프록시져.
       +- Main.h
       +- stdafx.cpp
       +- stdafx.h  // 프리컴파일헤더
      +- IME
       +- ImeBox.cpp // 각각의 ImeBox.
       +- ImeBox.h
       +- Ime.cpp  // ImeBase
       +- Ime.h
      +- Document
       +- ReadMe.txt // 지금 이문서.

//---------------------------------------------------------------------
 사용방법.
file://---------------------------------------------------------------------

 . 주석을 읽기가 귀찮으신분은 ImeBox.cpp ImeBox.h ime.cpp ime.h 를 그대로
가져다 쓰시고 main.cpp 부분을 참고하셔서 붙이시길 바랍니다.

 . 한국어외의 다른 ime 입력을 보장하지 않습니다.. (수고하세요)
 
 . ime 특유의.. 입력 오류시 띵띵~ 거리는 소리를 없에실 좋은 아이디어가 있
    으신 분은 연락을 주세요.

 . 소스를 편집 및 재배포 할시에는 연락을(홈페이지) 해주세용~♡ 재배포시
  에는 본문서에 하나의 파트를 만드시고.. 소스의 구성이나 편집한 부분.
  아직 해야할부분. 작성자 등을 남겨주세요.


//---------------------------------------------------------------------
 버전(버진 아님. -//-)
file://---------------------------------------------------------------------
v 0.1    kwonil 님의 도움으로.. 조합중이던 문자를 날렸음. - _-)V



출처 : http://blog.naver.com/cpp2angel?Redirect=Log&logNo=100007002652

[출처] IME 소스 (한글)|작성자 아발롱


반응형

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

ifdef, if defined, ifndef, if !defined  (0) 2011.03.04
enum, 보다 나은 enum  (0) 2011.01.13
[C++] 형변환 (Typecasting) - const_cast, reinterpret_cast, static_cast, dynamic_cast  (0) 2010.09.28
GameLoop (번역)  (0) 2010.09.16
IME 관련  (0) 2010.09.10
Posted by blueasa
, |

Arrays in C++/CLI

Programming/C++/CLI / 2010. 11. 26. 16:00
The article exposes the new array syntax available in C++/CLI for the declaration and use of CLI arrays

Introduction

Managed arrays are allocated on the CLI heap as opposed to native arrays which are allocated on the unmanaged C++ heap, which essentially means that they are typical garbage collected .NET objects. And throughout this article the term array will refer to a managed array, and if at all a native array is mentioned, it will explicitly be termed as a native array. Some of you might have seen my article on using managed arrays with the old MC++ syntax and I am sure a few of you would have let out pained groans at the really peculiar syntax. Well, those people should be delighted to know that C++/CLI supports managed arrays using a far more intuitive syntax than which existed in the older syntax.

Basic features

Here are some of the basic features of managed arrays in C++/CLI :-

  • Syntax resembles that of C++ templates
  • System::Array is automatic base type for all managed arrays
  • Allocated on the CLR heap (means they get Garbage Collected)
  • Rank of the array need not be 1 (arrays with rank 1 are called single dimensional and those with rank >1 are called multi dimensional)
  • Easily supports jagged arrays (unlike in the older syntax, jagged arrays are easier to declare and use)
  • Implicit conversion to and explicit conversion from System::Array BCL class
  • The rank and dimensions of an array object cannot be changed, once an array has been instantiated

Pseudo-template of an array type

The declaration and usage of array types in C++/CLI seems to use an imaginary template type (there is no such template of course, it�s all VC++ compiler magic) :-

 Collapse
namespace stdcli::language
{
    template<typename T, int rank = 1>
        ref class array : System::Array {};
}

array is declared inside the stdcli::language namespace so as to avoid conflicts with existing source code

Single dimensional array usage

Arrays of a reference type

 Collapse
ref class R
{
public:
    void Test1(int x)
    {
        array<String^>^ strarray = gcnew array<String^>(x);
        for(int i=0; i<x; i++)
            strarray[i] = String::Concat("Number ",i.ToString());
        for(int i=0; i<x; i++)
            Console::WriteLine(strarray[i]);
    }
};

The syntax does look different from that used for native arrays; C++ coders who have used templates should find this a lot more intuitive than people who come from a non-C++ background, but eventually they'll get comfortable with it.

Arrays of a value type

 Collapse
ref class R
{
public:
    void Test2(int x)
    {
        array<int>^ strarray = gcnew array<int>(x);
        for(int i=0; i<x; i++)
            strarray[i] = i * 10;
        for(int i=0; i<x; i++)
            Console::WriteLine(strarray[i]);
    }
};

Unlike in the old syntax, array syntax for value types is exactly the same as that for managed types.

Multi dimensional array usage

Multi dimensional arrays are managed arrays that have a rank greater than 1. They are not arrays of arrays (those are jagged arrays).

 Collapse
ref class R
{
public:
    void Test3()
    {
        array<String^,2>^ names = gcnew array<String^,2>(4,2);
        names[0,0] = "John";
        names[1,0] = "Tim";
        names[2,0] = "Nancy";
        names[3,0] = "Anitha";
        for(int i=0; i<4; i++)
            if(i%2==0)
                names[i,1] = "Brown";
            else
                names[i,1] = "Wilson";
        for(int i=0; i<4; i++)
            Console::WriteLine("{0} {1}",names[i,0],names[i,1]);
    }    
};

Jagged arrays

Jagged arrays are non-rectangular, and are actually arrays of arrays. The new template-style array syntax simplifies the declaration and use of jagged arrays, which is a major improvement over the old syntax where jagged arrays had to be artificially simulated by the developer.

 Collapse
ref class R
{
public:
  void Test()
  {
    array<array<int>^>^ arr = gcnew array<array<int>^> (5); 

    for(int i=0, j=10; i<5; i++, j+=10)
    {
      arr[i] = gcnew array<int> (j);
    }

    Console::WriteLine("Rank = {0}; Length = {1}",
      arr->Rank,arr->Length);
    /*
      Output :-
        Rank = 1; Length = 5
    */

    for(int i=0; i<5; i++)
      Console::WriteLine("Rank = {0}; Length = {1}",
        arr[i]->Rank,arr[i]->Length);
    /*
      Output :-
        Rank = 1; Length = 10
        Rank = 1; Length = 20
        Rank = 1; Length = 30
        Rank = 1; Length = 40
        Rank = 1; Length = 50
    */
  }
};

Using a typedef to simplify jagged array usage

 Collapse
typedef array<array<int>^> JaggedInt32Array;
typedef array<array<String^>^> JaggedStringArray;

ref class R
{
public:
    void Test()
    {
        JaggedInt32Array^ intarr = gcnew JaggedInt32Array(10);
        JaggedStringArray^ strarr = gcnew JaggedStringArray(15);        
    }
};

Directly initialize an array

The new syntax allows painless direct initialization of arrays.

 Collapse
ref class R1
{
public:
  void Test()
  {
    //Single dimensional arrays

    array<String^>^ arr1 = gcnew array<String^> {"Nish", "Colin"};
    array<String^>^ arr2 = {"Nish", "Smitha"};
    
    //Multi dimensional arrays

    array<Object^,2> ^ multiobarr = {{"Nish", 100}, {"Jambo", 200}};
  }
};

Arrays as function arguments

 Collapse
ref class R
{
public:
  void ShowStringArray(array<String^>^ strarr)
  {
    for(int i=0; i<strarr->Length; i++)
      Console::WriteLine(strarr[i]);
  }
  void Show2DInt32Array(array<int,2>^ arr)
  {    
    for(int i=0; i<arr->GetLength(0); i++)
    {
      Console::WriteLine("{0} times 2 is {1}",arr[i,0],arr[i,1]);
    }
  }
};

void _tmain()
{
  R^ r = gcnew R();
  r->ShowStringArray(gcnew array<String^> {"hello", "world"});
  array<int,2>^ arr = { {1,2}, {2,4}, {3,6}, {4,8} };
  r->Show2DInt32Array(arr);
}

//Output :-


/*
  hello
  world
  1 times 2 is 2
  2 times 2 is 4
  3 times 2 is 6
  4 times 2 is 8
*/

Returning arrays from functions

 Collapse
ref class R
{
public:
    array<String^>^ GetNames(int count)
    {
        array<String^>^ arr = gcnew array<String^>(count);
        for(int i=0; i<count; i++)
        {
            arr[i] = String::Concat("Mr. ",(i+1).ToString());
        }
        return arr;
    }

    void ShowNames(array<String^>^ arr)
    {
        for(int i=0; i<arr->Length; i++)
            Console::WriteLine(arr[i]);
    }
};

void _tmain()
{
    R^ r = gcnew R();
    array<String^>^ arr = r->GetNames(7);
    r->ShowNames(arr);
}

Array covariance

You can assign an array of type R to an array of type B, where B is a direct or indirect parent of R, and R is a ref class.

 Collapse
ref class R1
{
    //...

};

ref class R2 : R1
{
    //...

};

void _tmain()
{
    array<R1^>^ arr1 = gcnew array<R1^>(4);
    array<R2^>^ arr2 = gcnew array<R2^>(4);    
    
    array<R1^>^ arr3 = arr2;    
    array<R1^>^ arr4 = gcnew array<R2^>(4);    
}

Parameter arrays

C++/CLI has support for parameter arrays. There can only be one such parameter array per function and it also needs to be the last parameter.

 Collapse
ref class R
{
public:
    void Test(String^ s, [ParamArray] array<int>^ arr )    
    {
        Console::Write(s);
        for(int i=0; i<arr->Length; i++)
            Console::Write(" {0}",arr[i]);
        Console::WriteLine();
    }
};

void _tmain()
{
    R^ r = gcnew R();
    r->Test("Nish");
    r->Test("Nish",1);
    r->Test("Nish",1,15);
    r->Test("Nish",1,25,100);
}

Right now the only supported syntax uses the ParamArray attribute, but the eventual syntax will also support the simpler style shown below :-

  • void Test(String^ s, ... array<int>^ arr )

Calling System::Array methods

Since every C++/CLI array is implicitly a System::Array object, we can use System::Arraymethods on CLI arrays.

 Collapse
ref class R
{
public:
  bool CheckName(array<String^>^ strarr, String^ str)
  {
    Array::Sort(strarr);
    return Array::BinarySearch(strarr,str) < 0 ? false : true;
  }
};

void _tmain()
{
  R^ r = gcnew R();
  array<String^>^ strarr = {"Nish","Smitha",
    "Colin","Jambo","Kannan","David","Roger"};  
  Console::WriteLine("Nish is {0}",r->CheckName(strarr,"Nish") ? 
    gcnew String("Present") : gcnew String("Absent"));
  Console::WriteLine("John is {0}",r->CheckName(strarr,"John") ? 
    gcnew String("Present") : gcnew String("Absent"));
}

I've used System::Sort and System::BinarySearch in the above example.

Here's another snippet that clearly demonstrates the implicit conversion to System::Array.

 Collapse
ref class R
{
public:
    void ShowRank(Array^ a)
    {
        Console::WriteLine("Rank is {0}",a->Rank);
    }
};

void _tmain()
{
    R^ r = gcnew R();    
    r->ShowRank( gcnew array<int>(10) );
    r->ShowRank( gcnew array<String^,2>(10,2) );
    r->ShowRank( gcnew array<double,3>(10,3,2) );    
    r->ShowRank( gcnew array<int> {1,2,3} );
    r->ShowRank( gcnew array<int,2> {{1,2}, {2,3}, {3,4}} );
}

Arrays of non-CLI objects

You can declare C++/CLI arrays where the array type is of a non-CLI object. The only inhibition is that the type needs to be a pointer type. Consider the following native C++ class :-

 Collapse
#define Show(x) Console::WriteLine(x)

class N
{
public:
   N()
   {
      Show("N::ctor");
   }
   ~N()
   {
      Show("N::dtor");
   }
};

Now here's how you can declare an array of this type :-

 Collapse
ref class R
{
public:   
   void Test()
   {
      array<N*>^ arr = gcnew array<N*>(3);
      for(int i=0; i<arr->Length; i++)   
         arr[i] = new N();
   }
};

Put this class to use with the following test code :-

 Collapse
void _tmain()
{
   R^ r = gcnew R();
   r->Test();
   Show("Press any key...");
   Console::ReadKey();
}

/* Output:

N::ctor
N::ctor
N::ctor
Press any key...

*/

There, that worked. Of course the destructors for the array elements did not get called, and in fact they won't get called even if a Garbage Collection takes place and the array object is cleaned up. Since they are native objects on the standard C++ heap, they need to have delete called on them individually.

 Collapse
ref class R
{
public:   
   void Test()
   {
      array<N*>^ arr = gcnew array<N*>(3);
      for(int i=0; i<arr->Length; i++)   
         arr[i] = new N();
      for(int i=0; i<arr->Length; i++)   
         delete arr[i];
   }
   //...


/* Output

N::ctor
N::ctor
N::ctor
N::dtor
N::dtor
N::dtor
Press any key...

*/

Ok, that's much better now. Or if you want to avoid calling delete on each object, you can alternatively do something like this :-

 Collapse
ref class R
{
public:   
   void Test()
   {
      N narr[3];
      array<N*>^ arr = gcnew array<N*>(3);
      for(int i=0; i<arr->Length; i++)
         arr[i] = &narr[i];   
   }   
};

This yields similar results to the above snippet. Alternatively you could init the array members in its containing class's constructor and delete them in the destructor, and then use the containing class as an automatic variable (C++/CLI supports deterministic destruction).

Direct manipulation of CLI arrays using native pointers

Here's some code that shows how you can directly manipulate the contents of an array using native pointers. The first sample is for a single dimensional array and the second is for a jagged array.

Natively accessing a single-dimensional array

 Collapse
void Test1()    
{
    array<int>^ arr = gcnew array<int>(3);
    arr[0] = 100;
    arr[1] = 200;
    arr[2] = 300;

    Console::WriteLine(arr[0]);
    Console::WriteLine(arr[1]);
    Console::WriteLine(arr[2]);

    /*
    Output :-
      100
      200
      300
    */

    // Modifying the array using a native int* 

    // that points to a pinned pointer in GC'd heap

    pin_ptr<int> p1 = &arr[0];
    int* p2 = p1;
    while(*p2)
    {           
        (*p2)++;
        p2++;
    }

    Console::WriteLine(arr[0]);
    Console::WriteLine(arr[1]);
    Console::WriteLine(arr[2]);

    /*
    Output :-
      101
      201
      301
    */
} 

Natively accessing a jagged array

 Collapse
void Test2()
{
    array<array<int>^>^ arr = gcnew array<array<int>^>(2);
    arr[0] = gcnew array<int>(2);
    arr[1] = gcnew array<int>(2);
    arr[0][0] = 10;
    arr[0][1] = 100;
    arr[1][0] = 20;
    arr[1][1] = 200;

    Console::WriteLine(arr[0][0]);
    Console::WriteLine(arr[0][1]);
    Console::WriteLine(arr[1][0]);
    Console::WriteLine(arr[1][1]);

    /*
    Output:
      10
      100
      20
      200
    */


    // Copying the managed jagged array to

    // a native array of pointers and accessing

    // the members using the native array

    pin_ptr<int> p1 = &arr[0][0];
    pin_ptr<int> p2 = &arr[1][0];
    int* p3[2];
    p3[0] = p1;
    p3[1] = p2;

    Console::WriteLine(p3[0][0]);
    Console::WriteLine(p3[0][1]);
    Console::WriteLine(p3[1][0]);
    Console::WriteLine(p3[1][1]);

    /*
    Output:
      10
      100
      20
      200
    */

    // Assigning the native array of pointers

    // to a native int** and modifying the array

    int** p4 = p3;
    for(int i=0; i<2; i++)
        for(int j=0; j<2; j++)
            p4[i][j] += 3;          

    Console::WriteLine(arr[0][0]);
    Console::WriteLine(arr[0][1]);
    Console::WriteLine(arr[1][0]);
    Console::WriteLine(arr[1][1]);

    /*
    Output:
      13
      103
      23
      203
    */
}

Essentially we use a pinning pointer to the GC'd heap and then treat the casted native pointer as if it were pointing to a native array. Gives us a really fast method to manipulate array content!

Conclusion

Array syntax in C++/CLI is definitely an aesthetic improvement over the older MC++ syntax, and it also brings in a consistency of syntax that was severely lacking earlier. The template-style syntax should give a natural feel for C++ coders though it might take a little while before you fully get used to it. As usual, I request you to freely post any comments, suggestions, criticism, praise etc. that you might have for me.


출처 : http://www.codeproject.com/KB/mcpp/cppcliarrays.aspx

반응형
Posted by blueasa
, |

조치 방법은 일단 visual Studio IDE 를 삭제하고 다시 설치하는 방법이 있구요..(최악의 방법이자 뒷탈없는 방법이죠.)

 

다음으로는 Visual Studio IDE를 리셋 하는 방법입니다..

관련정보는 http://www.microsoft.com/korea/msdn/library/ko-kr/bb245788(vs.80).aspx

  • Visual Studio 2005의 인스턴스를 모두 종료합니다.
  • 시작을 클릭하고 실행...을 선택합니다.
  • "devenv.exe /resetuserdata"를 입력합니다.
이 명령을 사용하면 몇 분 동안 Visual Studio가 정리되고 처음 상태로 설정됩니다. 이때 작업 관리자를 열어 devenv.exe 프로세스가 실행 중인지 여부를 확인할 수 있습니다. 실행이 종료되면 Visual Studio를 다시 시작할 수 있습니다. 그러면 컴퓨터에서 Visual Studio를 처음으로 실행할 때처럼 처음 실행 대화 상자가 다시 표시됩니다.

반응형
Posted by blueasa
, |