๋ฐ˜์‘ํ˜•

์†Œ๊ฐœ

๋ณธ๋ฌธ์„ ์ฝ๊ธฐ ์ „์— C++/CLI๊ฐ€ ๋ฌด์—‡์ธ์ง€ ์ดํ•ดํ•˜๋ฉด ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ๋”ฐ๋ผ ํ•˜๋Š”๋ฐ ๋„์›€์ด ๋ฉ๋‹ˆ๋‹ค.

[.Net] C++/CLI ์ดํ•ดํ•˜๊ธฐ

 

[.Net] C++/CLI ์ดํ•ดํ•˜๊ธฐ

์†Œ๊ฐœ ์ง€๋‚œ ํฌ์ŠคํŒ…์—์„œ C# ํ”„๋กœ๊ทธ๋žจ ๊ฐœ๋ฐœ ์‹œ .Net Decompiler์— ์˜ํ•ด ์†Œ์Šค์ฝ”๋“œ๊ฐ€ ๋…ธ์ถœ๋  ์ˆ˜ ์žˆ๋Š” ์œ„ํ—˜์„ฑ์„ ์†Œ๊ฐœํ–ˆ์Šต๋‹ˆ๋‹ค. [.Net] .Net Framework์™€ ๋””์ปดํŒŒ์ผ๋Ÿฌ(Decompiler) ILSpy ๋ฐ dotPeek ์˜ˆ์ œ [.Net] .Net Fram..

luckygg.tistory.com

C++/CLI ์˜ˆ์ œ ๋งŒ๋“ค๊ธฐ

๊ฐ„๋‹จํ•˜๊ฒŒ C++/CLI ํ”„๋กœ์ ํŠธ์—์„œ ๋ง์…ˆ, ๋บ„์…ˆ, ๊ณฑ์…ˆ, ๋‚˜๋ˆ—์…ˆ ํ•จ์ˆ˜๋ฅผ ๋งŒ๋“ค์–ด C#์—์„œ ์‚ฌ์šฉํ•˜๋Š” ์˜ˆ์ œ ์ฝ”๋“œ๋ฅผ ์ž‘์„ฑํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ์‹ค์Šต์€ Visual Studio 2017๋กœ ์ง„ํ–‰ํ•˜๊ฒ ์Šต๋‹ˆ๋‹ค. ์˜ˆ์ œ ํŒŒ์ผ ๊ฒฐ๊ณผ ๋ฐ ์†Œ์Šค ์ฝ”๋“œ๋Š” ๋ณธ๋ฌธ ํ•˜๋‹จ์— ์žˆ์Šต๋‹ˆ๋‹ค.

๋จผ์ €, Visual Studio ๊ตฌ์„ฑ์œผ๋กœ C++/CLI๊ฐ€ ์„ค์น˜๋˜์–ด ์žˆ์–ด์•ผ ํ•˜๋Š”๋ฐ์š”. ์„ค์น˜๊ฐ€ ์•ˆ๋˜์–ด ์žˆ๋Š” ๊ฒฝ์šฐ ์•„๋ž˜ ์‚ฌ์ง„์ฒ˜๋Ÿผ ์„ค์น˜ ๊ตฌ์„ฑ์—์„œ 'C++/CLI ์ง€์›'์„ ํด๋ฆญํ•˜๊ณ  ์„ค์น˜ํ•˜์„ธ์š”. ์„ค์น˜ ํŒŒ์ผ ๋˜๋Š” 'ํ”„๋กœ๊ทธ๋žจ ๋ฐ ๊ธฐ๋Šฅ'์˜ Visual Studio 2017 ์„ ํƒ ํ›„ '๋ณ€๊ฒฝ'์„ ๋ˆ„๋ฅด๋ฉด ์•„๋ž˜ ํ™”๋ฉด์ด ํ‘œ์‹œ๋ฉ๋‹ˆ๋‹ค. ์„ ํƒ ํ›„ ๊ตฌ์„ฑ ํŒŒ์ผ์„ ์„ค์น˜ํ•ฉ๋‹ˆ๋‹ค.

Visual Studio ์„ค์น˜ ๋ณ€๊ฒฝ

์ค€๋น„๊ฐ€ ๋˜๋ฉด 'CLR ํด๋ž˜์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ'๋ฅผ ์„ ํƒํ•˜๊ณ  ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

CLR ํด๋ž˜์Šค ๋ผ์ด๋ธŒ๋Ÿฌ๋ฆฌ ์ƒ์„ฑ

ํ”„๋กœ์ ํŠธ ์ด๋ฆ„์€ 'Wrapper'๋กœ ์ƒ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค. ํ”„๋กœ์ ํŠธ๊ฐ€ ์ƒ์„ฑ๋˜๋ฉด Wrapper.h ๋ฐ cppํŒŒ์ผ์ด ๋ณด์ด๊ณ , ํ—ค๋” ํŒŒ์ผ์„ ์—ด์–ด ๋ณด๋ฉด C# ๋ฌธ๋ฒ•์ด ๋ณด์ž…๋‹ˆ๋‹ค. C#์€ ํ—ค๋” ํŒŒ์ผ๊ณผ ์†Œ์Šค ํŒŒ์ผ์ด ์—†๋Š”๋ฐ, ๋งˆ์น˜ C++์™€ C#์ด ๋’ค์„ž์ธ ๋Š๋‚Œ์ž…๋‹ˆ๋‹ค.

C++/CLI ๋ชจ์Šต

์ด์ œ Wrapper class์— ์‚ฌ์น™ ์—ฐ์‚ฐ์„ ์œ„ํ•œ ํ•จ์ˆ˜๋“ค์„ ํ—ค๋”์— ๋‹ค์Œ๊ณผ ๊ฐ™์ด ์ •์˜ํ•ฉ๋‹ˆ๋‹ค. ํด๋ž˜์Šค ๋ช…์€ MyArithmetic ์œผ๋กœ ์ •์˜ํ–ˆ์Šต๋‹ˆ๋‹ค.

#pragma once

using namespace System;

namespace Wrapper {
	public ref class MyArithmetic
	{
	public:
		int Add(int a, int b);
		int Subtract(int a, int b);
		float Multiply(float a, float b);
		float Divide(float a, float b);
	};
}

์†Œ์Šค ํŒŒ์ผ์—๋Š” ์•„๋ž˜์ฒ˜๋Ÿผ ๊ตฌํ˜„ํ•ฉ๋‹ˆ๋‹ค. ๋„ˆ๋ฌด ๊ฐ„๋‹จํ•ด์„œ ๋”ฐ๋กœ ์„ค๋ช…ํ•  ํ•„์š”๋Š” ์—†๊ฒ ์ฃ ?

#include "stdafx.h"
#include "Wrapper.h"

namespace Wrapper
{
	int MyArithmetic::Add(int a, int b)
	{
		return a + b;
	}

	int MyArithmetic::Subtract(int a, int b)
	{
		return a - b;
	}

	float MyArithmetic::Multiply(float a, float b)
	{
		return a * b;
	}

	float MyArithmetic::Divide(float a, float b)
	{
		return a / b;
	}
}

์ด๋ ‡๊ฒŒ ์ž‘์„ฑํ•œ ํ›„ ๋นŒ๋“œํ•˜๋ฉด ์ถœ๋ ฅ ๊ฒฝ๋กœ์— dll ํŒŒ์ผ์ด ์ƒ์„ฑ๋ฉ๋‹ˆ๋‹ค. ์ƒ์„ฑ๋œ dll์€ ์ดํ›„ C# ํ”„๋กœ์ ํŠธ์—์„œ ์‚ฌ์šฉ๋ฉ๋‹ˆ๋‹ค.

์ƒ์„ฑ๋œ dll ํŒŒ์ผ

์ด์ œ ์†”๋ฃจ์…˜์— C# ํ”„๋กœ์ ํŠธ๋ฅผ ํ•˜๋‚˜ ์ถ”๊ฐ€ํ•ด์•ผ ํ•ฉ๋‹ˆ๋‹ค. ์•„๋ž˜์ฒ˜๋Ÿผ '์ƒˆ ํ”„๋กœ์ ํŠธ' ๋ฉ”๋‰ด๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

ํ”„๋กœ์ ํŠธ ์ถ”๊ฐ€

์•„๋ž˜ ๊ทธ๋ฆผ์ฒ˜๋Ÿผ 'Windows Forms ์•ฑ'์„ ์„ ํƒํ•˜๊ณ  ํ”„๋กœ์ ํŠธ๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค.

C# ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ

ํ”„๋กœ์ ํŠธ ์ƒ์„ฑ์ด ์™„๋ฃŒ๋˜๋ฉด ์†”๋ฃจ์…˜ ํƒ์ƒ‰๊ธฐ์— ๋‘ ๊ฐœ์˜ ํ”„๋กœ์ ํŠธ๊ฐ€ ๋ณด์ž…๋‹ˆ๋‹ค. C# ํ”„๋กœ์ ํŠธ์˜ '์ฐธ์กฐ'์—์„œ ๋งˆ์šฐ์Šค ์˜ค๋ฅธ์ชฝ ๋ฒ„ํŠผ์„ ํด๋ฆญํ•˜๊ณ  '์ฐธ์กฐ ์ถ”๊ฐ€'๋ฅผ ์„ ํƒํ•ฉ๋‹ˆ๋‹ค.

์ฐธ์กฐ ์ถ”๊ฐ€

๊ทธ๋ฆฌ๊ณ  Wrapper ํ”„๋กœ์ ํŠธ์˜ ์ถœ๋ ฅ ๊ฒฝ๋กœ์—์„œ 'Wrapper.dll'์„ ์ฒดํฌํ•˜๊ณ  ์ถ”๊ฐ€ํ•ฉ๋‹ˆ๋‹ค.

Wrapper.dll ์ถ”๊ฐ€

์ •์ƒ์ ์œผ๋กœ ์ถ”๊ฐ€๋˜๋ฉด ์•„๋ž˜์ฒ˜๋Ÿผ '์ฐธ์กฐ'์— 'Wrapper' ํ•ญ๋ชฉ์ด ๋ณด์ž…๋‹ˆ๋‹ค.

Wrapper dll์ด ์ถ”๊ฐ€๋œ ๋ชจ์Šต

์ด์ œ C# ํ”„๋กœ์ ํŠธ์—์„œ MyArithmetic Class๋ฅผ ์ •์˜ํ•˜์—ฌ ์‚ฌ์น™์—ฐ์‚ฐ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•˜๋Š” ๋ฐฉ๋ฒ•์„ ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. ๋จผ์ € C# ํ”„๋กœ๊ทธ๋žจ์˜ UI๋Š” ์•„๋ž˜์ฒ˜๋Ÿผ ๊ตฌ์„ฑํ–ˆ์Šต๋‹ˆ๋‹ค.

C# ํ”„๋กœ๊ทธ๋žจ UI ๋ ˆ์ด์•„์›ƒ

์ฝ”๋“œ์—์„œ๋Š” using Wrapper; ๋ฅผ ์ถ”๊ฐ€ํ•˜๊ณ  MyArithmetic ๊ฐ์ฒด๋ฅผ ์ƒ์„ฑํ•ฉ๋‹ˆ๋‹ค. ๊ทธ๋ฆฌ๊ณ  ๊ฐ ๋ฒ„ํŠผ์˜ ์ด๋ฒคํŠธ์—์„œ๋Š” ์‚ฌ์น™์—ฐ์‚ฐ ํ•จ์ˆ˜๋“ค์„ ํ˜ธ์ถœํ•˜๋ฉด ๋ฉ๋‹ˆ๋‹ค.

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Forms;
using Wrapper; //namespace ์ถ”๊ฐ€

namespace WindowsFormsApp1
{
    public partial class Form1 : Form
    {
        MyArithmetic arithmetic = new MyArithmetic(); //๊ฐ์ฒด ์ƒ์„ฑ
        public Form1()
        {
            InitializeComponent();
        }

        private void buttonAdd_Click(object sender, EventArgs e)
        {
            int value = arithmetic.Add(Convert.ToInt32(textBox1.Text), Convert.ToInt32(textBox2.Text));
            textBoxResult.Text = value.ToString();
        }

        private void buttonSubtract_Click(object sender, EventArgs e)
        {
            int value = arithmetic.Subtract(Convert.ToInt32(textBox1.Text), Convert.ToInt32(textBox2.Text));
            textBoxResult.Text = value.ToString();
        }

        private void buttonMultiply_Click(object sender, EventArgs e)
        {
            float value = arithmetic.Multiply((float)Convert.ToDouble(textBox1.Text), (float)Convert.ToDouble(textBox2.Text));
            textBoxResult.Text = value.ToString();
        }

        private void buttonDivde_Click(object sender, EventArgs e)
        {
            float value = arithmetic.Divide((float)Convert.ToDouble(textBox1.Text), (float)Convert.ToDouble(textBox2.Text));
            textBoxResult.Text = value.ToString();
        }
    }
}

๊ฒฐ๊ณผ๋Š” ์•„๋ž˜์™€ ๊ฐ™์Šต๋‹ˆ๋‹ค. ์ž˜ ๋™์ž‘ํ•˜์ฃ ?

ํ”„๋กœ๊ทธ๋žจ ๊ฒฐ๊ณผ

๋งˆ์ง€๋ง‰์œผ๋กœ dotPeek๋กœ ์ƒ์„ฑ๋œ exeํŒŒ์ผ์„ ๋ถ„์„ํ•ด ๋ณด๊ฒ ์Šต๋‹ˆ๋‹ค. MyArithmetic ๊ฐ์ฒด๋กœ ์‚ฌ์น™์—ฐ์‚ฐ ํ•จ์ˆ˜๋ฅผ ํ˜ธ์ถœํ•œ ๊ฒƒ์ด ๋ณด์ด์ง€๋งŒ, ๋‚ด๋ถ€ ์—ฐ์‚ฐ ์ฝ”๋“œ๊นŒ์ง€๋Š” ๋…ธ์ถœ๋˜์ง€ ์•Š์Šต๋‹ˆ๋‹ค. ์ง์ ‘ ๋งŒ๋“  ์•Œ๊ณ ๋ฆฌ์ฆ˜์„ C# ํ•จ์ˆ˜์— ์ง์ ‘ ๊ตฌํ˜„ํ•˜๋ฉด ์ •๋ง ํฐ์ผ ๋‚˜๊ฒ ์ฃ ?

dotPeek๋กœ ๋…ธ์ถœ๋œ ์ฝ”๋“œ

์•„๋ž˜ ์ฒจ๋ถ€๋œ ์˜ˆ์ œ ํŒŒ์ผ์„ ์ฐธ๊ณ ํ•˜์„ธ์š”.

Wrapper.zip
0.06MB

๋ฐ˜์‘ํ˜•