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

카테고리

분류 전체보기 (2738)
Unity3D (817)
Programming (475)
Server (33)
Unreal (4)
Gamebryo (56)
Tip & Tech (228)
협업 (58)
3DS Max (3)
Game (12)
Utility (136)
Etc (96)
Link (32)
Portfolio (19)
Subject (90)
iOS,OSX (53)
Android (14)
Linux (5)
잉여 프로젝트 (2)
게임이야기 (3)
Memories (20)
Interest (38)
Thinking (38)
한글 (30)
PaperCraft (5)
Animation (408)
Wallpaper (2)
재테크 (18)
Exercise (3)
나만의 맛집 (3)
냥이 (10)
육아 (16)
Total
Today
Yesterday
05-04 00:00
반응형
Posted by blueasa
, |

C# 관련 사이트

Programming/C# / 2010. 5. 20. 14:05
반응형
Posted by blueasa
, |

이번에 파티클 에디터를 만들면서 mfc 말고 c# 을 사용해보았는데 c# 문법에 대한 자료는 많지만,

c++ lib 를 c# 에서 사용하는 방법에 대해 자세히 나온곳이 없어서 간단하게 정리해보았습니다.

 

작업순서는

1) c++ 로 lib 작성 (lib)

2) c++/cli 로 wrapper 를 만들고 (dll)

3) c# 에서 wrapper dll 를 호출해서 작업을 하게됩니다.

 

 

직접 해보자면

1) c++ 로 lib 를 하나 만듭니다. 저는 간단하게 다음과 같은 class 를 만들었습니다.

 

class cppLib

{

public :

        int     addValue( int value1, int value2 )

        {

               return ( value1 + value2 );

        }

};
 
 
2) 그 다음에는 c++/cli 로 프로젝트를 만듭니다.

 

 
 
이곳에서 아까 만든 lib 를 link 시켜서 wrapper class 를 만듭니다.
 
[ header ]

namespace cliWrap

{

        public ref class cppLibWrap

        {

        protected :

               cppLib *       m_pCppLib;

 

        public :

               cppLibWrap();

               virtual ~cppLibWrap();

 

               int     addValue( int value1, int value2 );

        };

 

} // namespace - cliWrap

 

 

[ source ]

namespace cliWrap

{

        cppLibWrap::cppLibWrap() : m_pCppLib( new cppLib )

        {}

 

        cppLibWrap::~cppLibWrap()

        {

               if( m_pCppLib )

               {

                       delete m_pCppLib;

                       m_pCppLib = 0;

               }

        }

 

        ////////////////////////////////////////////////////////// 

        int     cppLibWrap::addValue( int value1, int value2 )

        {

               return m_pCppLib->addValue( value1, value2 );

        }

 

} // namespace - cliWrap

 

 

3) wrapper class 작성이 끝났으면  c# 으로 프로젝트를 만듭니다.


 

c# 프로젝트 생성후에 위에서 작업한 2개의 프로젝트를 추가시켜줍니다.

 

wrapper class 쪽에서 만들어지는 dll 을 c# 에서 사용하게 되는데 매번 변경사항이

있을때마다 복사하기가 번거롭기 때문에 빌드시마다 자동으로 복사해주는 작업을 해줍시다.

 

 

Command Line 에 copy "$(TargetPath)" "$(SolutionDir)\simpleProject\$(TargetFileName)" 를

자신의 프로젝트 폴더에 맞게 적당히 수정해서 적어줍니다.

 

 

그 후에 dll 복사를 위해 wrapper 프로젝트를 다시 빌드해줍니다.

이제 c# 프로젝트에 c++/cli 로 만든 dll 을 붙여줍니다.
 

 

아까 만든 wrapper class dll 을 추가시켜줍니다.

 


 

 

이제 작업이 끝났습니다.

c# 프로젝트에서는 다음과 같이 그냥 사용하시면 됩니다.

 

namespace simpleProject

{

    public partial class Form1 : Form

    {

        private cliWrap.cppLibWrap m_cppLibWrap = null;

 

        public Form1()

        {

            InitializeComponent();

 

            m_cppLibWrap = new cliWrap.cppLibWrap();

 

            int returnValue = m_cppLibWrap.addValue(1, 2);

 

            MessageBox.Show(returnValue.ToString());

        }

    }

}
 

 
이제 Property Grid 를 비롯해 c# 의 막강한 기능을 누리시면 됩니다.
 
다음에는 c# 에서 Property Grid 를 붙힐때 c++ lib 작업시에 미리 등록을 해서
자동화하는 방법에 대해 설명하고자 하는데 언제가 될지는 모르겠습니다. 하하~
 
 
ps. c#, c++/cli 문법에 대한것은 인터넷에 많기때문에 이곳에서 다루지 않았습니다.
참고할만한 c# 서적이 pdf 로 공개되어있습니다. 참고하시길 바랍니다.
반응형
Posted by blueasa
, |

C++이 주력 프로그래밍 언어이고 VC++ MVP이니 2009년에 C++/CLI을 완전히 마스터해 볼 생각입니다.

아직까지는 네이티브 C++ 코드와의 연동 하는 경우가 적지 않으니 잘 알고 있으면 아주 유익하리라 생각합니다.

봄 이후부터는 조금씩이라도 C++/CLI 입문, C/C++과 C++/CLI 연동 관련 글을 포스팅 하겠습니다.

 

C++/CLI Quick Referrence

http://jundols.springnote.com/pages/1721142

C++/CLI Tutorial

http://www.functionx.com/cppcli/index.htm


C++/CLI Primer (영어)
http://www.codeguru.com/cpp/cpp/cpp_managed/general/article.php/c14815__1/


CodeGuru의 C++/CLI (영어)
http://www.codeguru.com/cpp/cpp/cpp_managed/


CodeProject의 C++/CLI (영어)
http://www.codeproject.com/KB/mcpp/



C++/CLI을 사용하여 C 라이브러리를 .NET화 하자  (일어)
http://codezine.jp/article/detail/1382?p=1


C++/CLI 입문 (일어)
http://www13.plala.or.jp/kmaeda/cpp_cli/cpp_cli.htm


C++ 프로그래머를 위한 C++/CLI 입문
http://cppcli.shacknet.nu/


C++/CLI 언어사양(Ecma 372) 일본어 번역 (일어)
http://vene.wankuma.com/ecma372/StartingState.aspx


C++/CLI Tip  (일어)
http://vene.wankuma.com/prog/CppCli_Generics.aspx


처음부터 시작하는 Visual C++ 2005 입문  (일어)
http://itpro.nikkeibp.co.jp/article/COLUMN/20061206/256112/?ST=develop

반응형
Posted by blueasa
, |

내가 만든 라이브러리가 제대로 동작하는지, 그리고, 이 라이브러리는 사용하는데 있어서 문제가 없는지를 확인하기 위해서, 이를 사용한 테스트 클라이언트를 만들기로 했다. , 여기에 C#을 사용하고 싶었다. C#에서 간단히 처리할 수 있는 문제를 가지고 MFC와 씨름하면서 시간을 허비하기는 싫었기 때문에

몇 가지 방법 중에 내가 선택한 방법은 C++/CLIC++라이브러리를 감싼 다음 이를 C#에서 사용하는 것이다. 이 방법을 선택한 이유는 순전히, 시도해본 다른 방법이 모두 실패했기 때문이다. 방법이 없다 라기보다는 내가 잘 모르고 익숙하지 않아서 그렇다. 그렇다고 C++/CLI를 사용하는데 익숙한가 하면, 그것도 아니다. C++/CLI는 정말인지 필요 없다고 생각한다. 딱 한가지만 빼고. 바로 C++라이브러리를 감싸는 것. 하여튼, C++/CLI를 하나도 몰랐다. 지금도 잘 모르는 상태이기 때문에, 아래에 내가 설명하는 내용에는 다소의 오류가 있을 수도 있음을 알아주기 바란다

C++/CLI C++의 문법을 이해한다. 이 말은 C++/CLI에서 Unmanaged Code를 사용할 수 있다는 의미이다. 따라서 C# C++/CLI의 문법을 100% 이해할 수는 없다. 기본적으로 C# Managed Code이기 때문이다. 따라서 C++/CLI C++라이브러리를 잘만 감싸면, C#에서 아무런 수고 없이 이를 사용할 수 있다. 참고로 내가 사용한 Visual Studio의 버전은 2005이다

Visual C++ CLR타입 Class Library 프로젝트를 생성하고, C++로 만든 라이브러리를 포함시킨다. 사실, 이것은 Unmanaged C++을 사용할 때의 라이브러리 사용과정과 전혀 다르지 않다. 이제부터 할 일은 C++라이브러리 중에서 노출할 필요가 있는 인터페이스들을 Managed C++로 작성해주기만 하면 된다. 이 글의 주요 주제 되겠다

C++의 데이터타입은 C++/CLI에서 아래의 표와 같이 바꾼다.

 

Unmanaged Data Type

Unmanaged Data Type

Ref.

class

ref class

 

struct

value struct

 

enum

enum class

 

std::string

String^

PtrToStringAnsi()

std::map

Dictionary^

 

std::vector

List^

 

std::list

List^

 

function pointer

delegate

 

 

반드시 이와 같이 할 필요는 없다. std::vector Array로 바꾸어도 전혀 상관없다. 목표는 C++에서 데이터를 다루듯이 C#에서 이를 다룰 수 있도록 하는 것이다

C++/CLI struct C++과는 달리, value-type으로만 사용된다. reference-type으로 사용하기위해서는 class를 사용해야 한다

ref class로 선언되지 않은 클래스는 GC(Garbage Collection)의 관리를 받지 않으며, Unmanaged Code이다

C++/CLI에서의 ^ C++ *에 해당한다. 따라서 ^형으로 선언된 변수는 gcnew키워드로 생성해야 한다. gcnew로 할당된 메모리는 GC가 자동으로 해제하므로, 그에 대해 신경 쓸 필요 없다

Unmanaged String Managed String에 직접 대입될 수 없으므로, PtrToStringAnsi()함수로 사전에 변환되어야 한다. 다음은 Managed String Unmanaged String사이에 사용되는 매크로이다

 
#define MANAGEDSTR(unmanaged_string) System::Runtime::InteropServices::Marshal::PtrToStringAnsi(IntPtr::IntPtr((void*) unmanaged_string))
#define UNMANAGEDSTR(managed_string) (LPSTR)(LPCTSTR)(CString(managed_string))

C++라이브러리에서 사용되는 함수 포인터는 C++/CLI에서 적절한 델리게이트로 바뀌어야한다. GetFunctionPointerForDelegate()함수를 사용할 수도 있지만, 나의 경우는 좀 더 간단하게, Unmanaged Code로 작성한 콜백함수에서 Managed Code로 작성한 콜백함수(델리게이트)를 호출했다. 가장 까다롭게 생각했고, 실제로 시간도 많이 잡아먹은 부분이 콜백함수의 처리였지만, 의외로 싱겁게 끝나버렸다

이렇게 만들어진 라이브러리는 C#에서 바로 사용할 수 있다. 모든 인터페이스를 Managed Code로 재 작성 해야 한다는 번거로움이 있긴 하지만, 적어도 내 생각에는 이것이 가장 무난하고 또, 만만한 방법이라고 생각된다.


출처 : http://www.dogfootlife.com/archives/73

반응형
Posted by blueasa
, |

C# 강좌 사이트

Programming/C# / 2010. 5. 14. 19:37
반응형
Posted by blueasa
, |





2. codeproject(코드프로젝트) http://www.codeproject.com/

각종 오픈 소스/라이브러리를 다운받을 수 있음



3. c-sharpcorner(시샾코너) http://www.c-sharpcorner.com/Default.aspx

각종 오픈 소스/라이브러리를 다운받을 수 있음



4. Devpia(데브피아) http://www.devpia.com/CSharp.MAEUL

기초 강좌, 예제소스, 그리고 활발한 Q&A가 이뤄지는 국내 커뮤니티 싸이트




기초 강좌, 예제소스, 그리고 활발한 Q&A가 이뤄지는 국내 커뮤니티 싸이트


 

출처 : http://youngik.tistory.com/entry/C-공부하기-도움되는-각종-Source-다운-라이브러리-참조-싸이트

반응형
Posted by blueasa
, |

프로그램의 오류를 찾기 위해 가장 기본적으로 쓰는 기능 중 하나가 바로  assert 문 입니다.

 

사용법은 다음과 같지요.

 

#include <assert.h>              // C++ 로는 #include <cassert>

 

Pointer* p = new Pointer();      // 임의로 메모리를 할당하곤

 

assert( p != NULL );               // 메모리가 할당되지 않았다면 메세지 박스와 함께 프로그램이 죽습니다.

 

...                                        // 그렇지 않으면 프로그램은 계속 실행되겠죠.

 

보다시피 사용방법은 매우 직관적입니다.

 

assert( p != NULL ); 구문은 디버그 모드에서만 작동되며 p가 반드시 NULL이 아니어야 한다는 조건을 부여합니다. 따라서, p가  NULL 이라면 메세지 박스가 활성화 되면서 assert가 걸린 라인 수까지 표시가 되지요.

 

물론 릴리즈 모드로 컴파일하면 위의 구문들은 모두 생략됩니다.

 

 

 

이제, 기본적인 사용방법을 알았으니 추가적인 비법을 알려드리지요.

 

 #include  <assert.h>              // C++ 로는 #include <cassert>

 

Pointer* p = new Pointer();      // 임의로 메모리를 할당하곤

 

assert( p != NULL && "포인터 메모리 할당을 실패했잖아" );             

 

...                                        // 그렇지 않으면 프로그램은 계속 실행되겠죠.

 

결과는 메세지 박스에 "포인터 메모리 할당을 실패했잖아" 라는 문구까지 부가적으로 표시됩니다.

 

 

매우 간단한 반면 그 기능은 탁월합니다. 저 같은 경우는 항상 포인터 NULL  여부 및 인덱스 참조 시에  assert 문을 사용하곤 합니다만

 

여러분도 필요한 곳에 사용하시길 바랍니다.

[출처] assert 문 사용하기|작성자 Hermet


반응형

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

A * pA = new B 과 B * pB = new B의 차이점.  (0) 2010.06.21
__super C++ 키워드  (0) 2010.06.03
[펌] try-catch 예외처리 비용?  (0) 2010.05.13
[펌] 순수 가상 소멸자  (2) 2010.05.06
C/C++에서 assert  (0) 2010.05.03
Posted by blueasa
, |

본 글을 읽기 전에 다음 글을 읽으시면 도움이 됩니다.  http://hermet.pe.kr/92422706 (c++ 예외처리), 

 

 

예전부터 궁금한 사실이었지만,   과연 try - catch를 사용함에 따른 비용은 어느정도일까?

 

궁금해서 직접 c++을 통해 테스트 해보기로 했습니다.

 

 #define ENABLE_EXCEPTION

 

struct Test {
      int    m[100];
      Test() { printf( "." ); }
 };

 

int _tmain(int argc, _TCHAR* argv[])
{

          DWORD begin = GetTickCount();

      

          for( int idx = 0; idx < 1000000; ++idx ) {

 #ifdef ENABLE_EXCEPTION
         try {
                Test* test = new Test();        delete( test );
         }catch( ... ) {    printf( "Exception!\n" );        }
 #else
         Test* test = new Test();
         delete( test );
#endif
}       

          DWORD end = GetTickCount();

          printf( "Elapsed - %d\n", end - begin );
          return 0;
}

 

위 코드에 대해 주목할 것은 어떤 임의의 루프문에서 Test라는 객체를 생성하고 제거하는 것인데,  예외처리 지정일 경우 try - catch 문에서 이를 수행한다는 것입니다.

 

그럼 과연 try-catch를 했을 경우와 하지 않았을 경우의 출력 값은 어떠했을까?

 

예외 처리한 결과 - 85723

안한 결과 -          76503

 

성능 결과는 무려 9초 차이가 납니다. 그리고 언어마다 그 차이는 조금씩 다르겠죠. (매우 클 수도 있고.. -_- )

 

그래도 확실한 것은,  try - catch에 의한 비용은 분명히 있습니다.

 

자, 어찌됐든 위 코드에서 우리는 메모리 할당의 예외 가능성을 예측할 수 있으므로 다음과 같이 수정해 봅시다.

 

 Test* test = new Test();

 

if( test ) {

    delete( test );

}else {

      printf( "Exception!\n");

}

 

그리고 시간 측정 결과는 다음과 같습니다.

 

예외 처리한 결과 - 85723

안한 결과 -          76503

나의 예외처리 -      78671

 

아무것도 하지 않는 것보다는 약 2초 가량 더 부하가 있긴 하지만, try-catch보단 월등히 낫군요.

 

사실, 시스템 사양에 따라 이런 예외처리 부하는 매우 미미할 수 있을 것이며 80:20 법칙을 고려했을 때도 이는 전체 성능에 거의 눈에 띄지 않을 수도 있겠죠.

 

결국, 예외처리에 대한  선택의 여지는 여러분의 몫이 될 수 밖에 없습니다.

 

 

그리고 예외처리에 대한 저의 철학은 다음과 같습니다.

 

 

"피할수 있다면 하지 않는다."

 

 

try-catch 문에 대해선 위 예와 같이 피할 수 있으면 하지 않습니다. 시스템 콜 사용에 대해선 결과를 알 수 있으므로 대부분 하지 않겠죠.

또한 라이브러리 제작 측면에서는 사용자의 잘못된 사용에 대해 if-else 대신 assert (http://hermet.pe.kr/54763810 )로 사전에 방지해 줍니다. 개발 과정에서는 debug 모드로 제작을 하면서 모든 에러 및 잘못된 사용에 대해 사용자들에게 assert로 알려주는 것이지요.

 

그리고 제품 release일 경우엔 이 assert문은 자연스럽게 코드에서 빠지면서 예외처리에 대한 부하도 같이 사라지게 됩니다.

물론 개발과정에서 assert문을 통해 모든 오류를 수정한 후 일것이구요.

 

More Effective C++ 책에 의하면, try - catch 블록을 쓰기만 해도 코드 블록 및 실행 속도가 5 ~ 10 % 늘어난다고 합니다.

또한, 실제 예외가 발생(throw)하여 함수로 복귀하는데에는 1000배 만큼 느려진다고 합니다. 물론 예외는 거의 발생하지 않는다 라고 봤을 때 이런 부하는 눈감아 줄 수도 있겠죠.

 

 

결론을 말하죠.

 

쓸데없이 예외처리를 하지는 마세요. 진짜 예외적인 상황이 발생할 수 있을 때만 합니다.

성능이 문제가 된다면 위 예제 소스와  같이 프로파일링을 해보세요.

그리고 컴파일러 옵션에서 예외지정을 제외하세요.

 

 

 

(참고 - More Effective C++ (정보문화사), 132-134 )


반응형

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

__super C++ 키워드  (0) 2010.06.03
[펌] assert 문 사용하기  (0) 2010.05.13
[펌] 순수 가상 소멸자  (2) 2010.05.06
C/C++에서 assert  (0) 2010.05.03
TCHAR에 관한여...  (0) 2010.04.29
Posted by blueasa
, |

MFC 기초 강좌

Programming/MFC / 2010. 5. 10. 22:24
반응형
Posted by blueasa
, |