C# C++ 혼합 프로그래밍 4장
8. C#에서 Native 다이렉트 X 호출 dx_wrapping.zip다이렉트 X 디바이스를 생성해서 파란 화면을 보여주는 간단한 프로그램을 만들어 보자 !!!
Native 다이렉트 X를 호출 할려면 디바이스나 핸들의 값을 C#과 어떻게 통신 할것인지 고민 하게 되었다.
System.IntPtr을 이용 하면 통신이 가능하다는 것을 알게 되었다.
포인터나 핸들은 IntPtr 이용해 받기System.IntPtr을 사용하면 포인터나 핸들을 네이티브로 보내거나 받을수 있다.
C#에서 DllImport를 사용해서 윈도우즈 API 함수를 호출할 때, IntPtr을 본적이 있을 것이다.
[DllImport("user32.dll")]
static extern IntPtr FindWindow(string lpClassName, string lpWindowName);
IntPtr.ToPointer()를 이용해서 C# Form의 윈도우 핸들을 Native C++로 넘겨주는 예는 많이 있지만,
Nativ C++에서 ,C#으로 넘겨주는 윈도우 핸들이나 포인터의 정확한 문서는 찾을수가 없었다.
DllImport 경우를 생각해서 아래 예제를 만들어 보면 "hWnd", "IPtr", "window" 3개의 값은 모두 똑같다.
HWND hWnd = ::FindWindow("Notepad", "제목 없음 - 메모장");
IntPtr iPtr = (IntPtr)hWnd;
HWND window = (HWND)iPtr.ToPointer();
프로그램에 사용되는 파일들은 다음과 같다.
Unmanaged C++graphics.cpp, graphics.hCGraphics 클래스
다이렉트 X 디바이스를 생성해서 빈화면을 렌더링Managed C++mgraphics.cppMGraphics 클래스CGraphics 클래스 랩핑C#dxmain.csDXMain 클래스MGraphics 클래스를 참조하여 렌더링한다.앞장과는 다르게 Unmanaged C++과 Managed C++을 별도의 DLL로 만들지 않고 graphics.dll 하나로 만든다.
CGraphics 클래스는 압축 파일의 소스를 참고하고, MGraphics 클래스는 리스트만 보여줄것이다.
설명은 C# 부분만 자세하게 한다.
아직 C#에 익숙하지 않기 때문에 틀린 설명도 있을 것이다.
MGraphics 클래스는 다이렉트 X 디바이스를 생성, 렌더링, 소멸을 랩핑 하였다.
생성, 렌더링, 소멸을 DXMain 클래스 어디서 해줄건지 알면 문제는 쉽게 풀수 있다.
생성: WinForm이 화면에 출력되기 전에 Load 이벤트 발생
렌더링: WinForm 이벤트 없을 때 Idle 이벤트 발생
소멸: WinForm을 닫을 때 Closed 이벤트 발생
이벤트를 사용 할려면 이벤트를 생성자에 추가한다.
이벤트 등록: public DXMain(string strText)
{
this.Text = strText;
this.Load += new System.EventHandler(this.Form_Load);
this.Closed += new System.EventHandler(this.Form_Closed);
Application.Idle += new System.EventHandler(this.Form_Idle);
//InitializeComponent();
this.Show();
}
생성 : private void Form_Load(object sender, System.EventArgs e)
{
dxRender = new MGraphics();
dxRender.Create(this.Handle);
dxRender.SetupCamera();
}
렌더링 : private void Form_Idle(object sender, System.EventArgs e)
{
dxRender.BeginScene();
dxRender.EndScene();
}
소멸 : private void Form_Closed(object sender, System.EventArgs e)
{
dxRender.Cleanup();
}
//mgraphis.cpp
#include
#using
using namespace System;
#include "graphics.h"
public __gc class MGraphics
{
public:
MGraphics()
{
m_pUnmanagedGraphics = new CGraphics();
}
~MGraphics()
{
delete m_pUnmanagedGraphics;
}
public:
bool Create(IntPtr windowHandle)
{
HWND hWnd = (HWND)windowHandle.ToPointer();
RECT rect;
GetClientRect(hWnd, &rect);
return m_pUnmanagedGraphics->Create(hWnd, rect.right - rect.left, rect.bottom - rect.top, false);
}
void Cleanup()
{
m_pUnmanagedGraphics->Cleanup();
}
void SetupCamera()
{
m_pUnmanagedGraphics->SetupCamera();
}
void BeginScene()
{
m_pUnmanagedGraphics->BeginScene();
}
IntPtr EndScene()
{
return m_pUnmanagedGraphics->EndScene();
}
private:
CGraphics * m_pUnmanagedGraphics;
};
//dxmain.cs
using System;
using System.Windows.Forms;
public class DXMain : Form
{
private MGraphics dxRender = null;
public DXMain(string strText)
{
this.Text = strText;
this.Load += new System.EventHandler(this.Form_Load);
this.Closed += new System.EventHandler(this.Form_Closed);
Application.Idle += new System.EventHandler(this.Form_Idle);
//InitializeComponent();
this.Show();
}
[STAThread]
static void Main()
{
Application.Run(new DXMain("DirectX Test"));
}
private void Form_Load(object sender, System.EventArgs e)
{
dxRender = new MGraphics();
dxRender.Create(this.Handle);
dxRender.SetupCamera();
}
private void Form_Closed(object sender, System.EventArgs e)
{
dxRender.Cleanup();
}
private void Form_Idle(object sender, System.EventArgs e)
{
dxRender.BeginScene();
dxRender.EndScene();
}
/*
protected override void OnPaint(PaintEventArgs e)
{
Form_Idle(this, e);
}
protected override void OnPaintBackground(PaintEventArgs e)
{
Form_Idle(this, e);
}
*/
}
[펌]http://www.gamedev.net/community/forums/topic.asp?topic_id=474894
[펌]Game Engine Toolset Development (출판사: Course Technology)
www.courseptr.com/downloads/bonus/009638_BonusCh02.pdf[출처] [C#]포인터나 핸들은 IntPtr 이용해 받기|작성자 nimi315
[출처] [펌] [C#]포인터나 핸들은 IntPtr 이용해 받기|작성자 baek2187
'개발언어 > C#' 카테고리의 다른 글
[C#] WinAPI(Kernel32 dll) 사용하기 (0) | 2020.11.03 |
---|---|
[C#] if ~else if를 한 줄로 '삼항 연산자' (0) | 2020.11.03 |
[c#] [StructLayout(LayoutKind.Sequential)] (0) | 2020.11.02 |
[C#] - internal 접근 한정자 (0) | 2020.11.02 |
[C#] ref 키워드와 out 키워드의 차이 (0) | 2020.11.02 |