코딩 하다보니까 조금 헷갈려서 확인차 이것 저것 해보다보니 더 헷갈렸다.

C#의 reference, value참조에 대해서 MSDN에 나와 있는 것 + 구글링 한 내용으로 정리 해 본다.

 

코드를 보는게 가장 빠르다.

 

Call By Value 

 public void CallByValue(int a)

{

a = 100;

}

 

static void main(string args[])

{

int test = 0;

CallByValue(test);

Console.WriteLine(test);

}

 

결과는 0

 

Call By Reference 

 public void CallByReference(ref int a)

{

a = 100;

}

 

static void main(string args[])

{

int test = 0;

CallByReference(test);

Console.WriteLine(test);

}

 

결과는 100

참고로 out을 써도 되는데 ref와 out에는 다음과 같은 차이가 있다.

out : 초기화 안되도 됨

ref : 초기화 되어야만 함

 

Class경우

 public class A

{

    public int m_Int = 0;

}

 

// 파라미터로 입력되는 A의 Instance에 대한 참조 카운터가 1개 증가

public Function1(A param)

{

    //참조카운터 2 상태 (main에서 사용하는 instance와 이 함수의 param)

    param.m_Int = 100;

   

    // 동일 메모리를 가리키는 하나의 포인터 제거 의미

    // 참조 카운터 1상태 (main에서 사용하는 instance는 메모리에 할당 된 A를 여전히 가리킴)

    param = null;

}

 

// 파라미터로 입력되는 A의 Instance에 대한 참조 카운터가 그대로 유지

public Function2(ref A param)

{

    //참조 카운터가 증가하지 않음

    // main의 instance를 param이라는 이름으로 바꿔 쓰는 의미

    param.m_int = 100;

   

    // param이 가리키는 메모리에 대한 참조 카운터가 0이 되어 메모리 에서 릴리즈 된다.

    // 더이상 main의 instance도 null이다.

    param = null;

 

}

 

 

static void main(string args[])

{

A instance = new A();

Function1(instance);

Console.WriteLine(instance.m_int);  //100 출력, instance는 여전히 메모리에 할당 된 영역 가리킴

 

Function2(instance);

Console.WriteLine(Instance.m_int); // Instance는 null이므로 에러가 발생한다.

 

}

 

Structure의 경우

 public structure A

{

    public int m_Int = 0;

}

 

// 구조체는 instance의 값이 param에 복사된다.

public Function1(A param)

{

    param.m_Int = 100;   

    param = null;

}

 

public Function2(ref A param)

{

    // main의 instance를 param이라는 이름으로 바꿔 쓰는 의미

    param.m_int = 100;

   

    // param이 가리키는 메모리에 대한 참조 카운터가 0이 되어 메모리 에서 릴리즈 된다.

    // main의 instance도 이제 null이다.

    param = null;

 

}

 

 

static void main(string args[])

{

A instance = new A();

Function1(instance);

Console.WriteLine(instance.m_int);  //0 출력, instance는 Function1에 값만 복사 해 줬다.

 

Function2(instance);

Console.WriteLine(Instance.m_int); // Instance의 m_int는 100이 되었다.그러나 instance가 null이 되어

                                                  // 이 문구에서 에러가 발생하게 된다. 

}

 

http://msdn.microsoft.com/en-us/library/0f66670z.aspx 

이 문서를 참조 하였다.

 

'프로그래밍 > 기타' 카테고리의 다른 글

UML-클래스다이어그램 관계 정리  (1) 2015.01.15
Posted by 굿쟌
,

다음과 같은 폼으로 헤더파일을 만들어 주면, #ifndef 전처리 문으로 인해

2번째 선언시에 _CLASS_ 상수가 정의 되어 있어서 중복선언을 막아준다. 

 

전방선언 하고 헤더를 소스파일 cpp에 넣어서 교차포함을 피하는 방법도

있기는 하지만,이것저것 오류가 나는 경우가 굉장히 많았다.

 

이 방법이 그냥 단순무식 하면서도 편하게 코딩 할 수 있는 방법인듯 하다.

 

// class 헤더의 선언

// "class.h"

 

 #ifndef _CLASS_

 

#define _CLASS_                   

#include "포함할 헤더파일"

[클래스 및 함수 선언]

 

#endif

    

 

 

 

 

 

 

 

 

 

 

 

 // class 소스파일

// "class.cpp"

 

#include "stdafx.h"

#include "class.h"

 

[클래스 및 함수 정의]

 

미리 컴파일 된 헤더파일을 사용하면 헤더에 헤더를 포함해 주지 않아도

stdafx.h에 선언된 클래스를 class.h에서 사용 할 수 있다.

 

단, 소스파일에서 stdafx.h를 반드시 추가시켜 줘야 미리 컴파일 된 헤더를 사용할 수 있다.

참고로 stdafx.h 이전에 포함 된 헤더파일은 모두 무시 되니, 이 점을 꼭 고려해야 한다.

 

Posted by 굿쟌
,

가상 메모리를 RAM보다 더 큰 크기로 할당 할 수 있는 비밀은 HDD의 일부를 SWAP FILE로 사용하여 RAM의 상태를 저장하는데 있다. 이 부분에 대해서 정리한 파일을 올려본다. 사진은 보고 있는 "뇌를 자극하는 Windows System Programming"에서 발췌하였다.

 

 

 

 

 

 

'프로그래밍 > WinSysProgram' 카테고리의 다른 글

가상메모리 (1)  (0) 2015.01.16
16비트 CPU 명령어 설계  (0) 2014.10.25
간단한 CPU 구조  (0) 2014.10.25
Posted by 굿쟌
,

 뇌를 자극하는 Windows 시스템 프로그래밍에서 가상 메모리에 대한 내용 즉, "어떻게 각 프로세스에게 실제 메인 메모리 ( RAM ) 용량보다 많은 메모리를 할당 할 수 있는가"에 대한 해답을 정리한 내용이다.

 

공부를 할 수록 그동안 모르고 있던 것을 알게되어 기쁘다. 사실 현업에서는 별 필요 없는 이론적인 이야기지만, 그동안 몰랐던 것을 알게되니 안보이던 것들이 보여 시야가 넓어지는 기분이다.

 

 

 

'프로그래밍 > WinSysProgram' 카테고리의 다른 글

가상 메모리 (2)  (0) 2015.01.18
16비트 CPU 명령어 설계  (0) 2014.10.25
간단한 CPU 구조  (0) 2014.10.25
Posted by 굿쟌
,

 C# 으로 외부 SDK를 DllImport해서 사용하는 도중에 아래와 같은 런타임 에러가 발생했다.

 

 

"CreateSceneInstance'에 대한 호출 결과 스택이 불안정하게 되었습니다. 관리되는 PInvoke 시그니처와 관리되지 않는 대상 시그니처가 일치하지 않기 때문인 것 같습니다. 호출 규칙 및 PInvoke 시그니처의 매개 변수와 관리되지 않는 대상 시그니처가 일치하는지 확인하십시오."

 

라는 런타임 에러인데... SDK가 외국 회사 SDK라서 물어보기도 애매한데 에러가 나서 당황했지만, SDK에 포함되어 있는 샘플 프로그램과 하나하나 비교해보니 샘플 프로그램은 닷넷 2.0으로, 내가 짜는 프로그램은 닷넷 4.0을 기준으로 설정되어 있는 것을 확인 했다.

 

그래서 내가 만든 프로젝트도 닷넷 2.0으로 설정을 바꾸니 이 에러 없이 정상 동작 한다.. ㅎㅎ

 

 

 

인터넷에서 검색을 해봐도 이 에러가 발생했을 때, 닷넷 프레임 워크 3.5이하 버전으로 대상 프레임 워크를 변경하면 된다는 답변이 있었다.. 그래도 뭔가 이렇게 끝내려고 하니 안 닦고 나온 기분이라 좀더 검색을 해봤는데, 이 문제의 원인은 DLL파일을 Import할 때 함수 호출규약 CallingConvention을 DLL파일과 동일하게 설정해 주지 않았기 때문이란다.

 

닷넷 4.0부터는 DllImport할 때 CallingConvention을 지정하지 않는 경우 무조건 __stdcall로 간주하고 함수를 가져오는데, 이 때문에 dll에 들어 있는 함수와 실제 부르려고 하는 함수간 호출규약이 다르면 이런 에러가 날 수 있다고 한다.

 

이제 함수를 부를 때 아래와 같이 실제 CallingConvenction을 명기해주면, 정상적으로 런타임 에러 없이 프로그램이 동작한다.

 

출처 : 다음 블로그 어딘가 impactlife라는 분이 남기신 댓글에서 이 정보를 얻었다. 2013년에 올리신 답변이 2015년에

         어떤 초보 개발자를 구했다. 감사하다는 말을 남긴다.

 

Posted by 굿쟌
,

 

프로그램 개발 하기 전에 나는 클래스 다이어그램과 시퀀스 다이어그램만 그리는데, 매번 그릴때마다 헷갈려서 이렇게 정리해 봤다. 점선도 매번 햇갈려서 같이 넣어봤다. ㅋ

Posted by 굿쟌
,