클래스 구조의 C++ DLL 사용하기

 

이번에는 클래스 구조의 C++ DLL 사용하는 방법을 알아보곘습니다.


DLL 파일 준비하기

 

https://rurustory.com/12

 

[C++] 클래스를 DLL로 만들고 사용하기

클래스를 DLL로 만들고 사용하기 클래스를 DLL로 만들고 사용하는 방법을 알아보겠습니다. 클래스 구조 코드 준비하기 헤더파일(.h파일) #include using std::cout; using std::endl; #include using std::string; class

rurustory.com

 

저는 지난번 포스팅에서 만든 DLL를 사용하여 만들겠습니다.

 

DLL 구조

#include "ctest.h"
#define DLL __declspec(dllexport)

extern "C" {
	DLL TestClass* CreateTestClass();

	DLL void SetString(TestClass* obj, string data);
	DLL void SetBool(TestClass* obj, bool data);
	DLL void SetInt(TestClass* obj, int data);

	DLL string GetString(TestClass* obj);
	DLL bool GetBool(TestClass* obj);
	DLL int GetInt(TestClass* obj);

	DLL void DeleteTestClass(TestClass* obj);
}

DLL 호출하기

 

C#에서는 C++과 다르게 헤더파일(.h)이 필요가 없습니다.

 

DllImport 라는 함수를 사용하여 DLL의 함수를 가져올수 있습니다.

[DllImport("DLL 경로와 파일명")]
사용할 함수();

 


DLL 함수 클래스로 감싸기

 

사실 클래스로 감싸지않고 바로 사용을 할 수도 있지만 나중에 좀 더 사용하기 편하게 DLL를 C# 클래스 형태로 만들어보겠습니다.

 

코드

using System;
using System.Runtime.InteropServices;

namespace DLLTest
{
    class TestClass
    {
        [DllImport("D:\\C_Project\\ctest\\x64\\Release\\ctest.dll", CallingConvention = CallingConvention.Cdecl)]
        static private extern IntPtr CreateTestClass();

        [DllImport("D:\\C_Project\\ctest\\x64\\Release\\ctest.dll", CallingConvention = CallingConvention.Cdecl)]
        static private extern void SetBool(IntPtr obj, bool data);

        [DllImport("D:\\C_Project\\ctest\\x64\\Release\\ctest.dll", CallingConvention = CallingConvention.Cdecl)]
        static private extern void SetInt(IntPtr obj, int data);

        [DllImport("D:\\C_Project\\ctest\\x64\\Release\\ctest.dll", CallingConvention = CallingConvention.Cdecl)]
        static private extern bool GetBool(IntPtr obj);

        [DllImport("D:\\C_Project\\ctest\\x64\\Release\\ctest.dll", CallingConvention = CallingConvention.Cdecl)]
        static private extern int GetInt(IntPtr obj);

        [DllImport("D:\\C_Project\\ctest\\x64\\Release\\ctest.dll", CallingConvention = CallingConvention.Cdecl)]
        static private extern void DeleteTestClass(IntPtr obj);

        private IntPtr obj;

        public TestClass()
        {
            obj = CreateTestClass();
        }

        ~TestClass()
        {
            DeleteTestClass(obj);
        }

        public void SetBool(bool data) { SetBool(obj, data); }
        public void SetInt(int data) { SetInt(obj, data); }

        public bool GetBool() { return GetBool(obj); }
        public int GetInt() { return GetInt(obj); }

    }
}

 

코드 설명

[DllImport("D:\\C_Project\\ctest\\x64\\Release\\ctest.dll", CallingConvention = CallingConvention.Cdecl)]
static private extern IntPtr CreateTestClass();

[DllImport("D:\\C_Project\\ctest\\x64\\Release\\ctest.dll", CallingConvention = CallingConvention.Cdecl)]
static private extern void SetBool(IntPtr obj, bool data);

[DllImport("D:\\C_Project\\ctest\\x64\\Release\\ctest.dll", CallingConvention = CallingConvention.Cdecl)]
static private extern void SetInt(IntPtr obj, int data);

[DllImport("D:\\C_Project\\ctest\\x64\\Release\\ctest.dll", CallingConvention = CallingConvention.Cdecl)]
static private extern bool GetBool(IntPtr obj);

[DllImport("D:\\C_Project\\ctest\\x64\\Release\\ctest.dll", CallingConvention = CallingConvention.Cdecl)]
static private extern int GetInt(IntPtr obj);

[DllImport("D:\\C_Project\\ctest\\x64\\Release\\ctest.dll", CallingConvention = CallingConvention.Cdecl)]
static private extern void DeleteTestClass(IntPtr obj);

 

먼저 DllImport 를 이용하여 DLL의 함수들을 가져옵니다.

C#에서는 IntPtr 를이용하여 C++의 오브젝트 주소를 가져올 수 있습니다.

 

private IntPtr obj;

public TestClass()
{
    obj = CreateTestClass();
}

~TestClass()
{
    DeleteTestClass(obj);
}

 

IntPtr 형태의 obj를 생성하고 생성자에서 C++에서 만들어 놓은 CreateTestClass()를 이용하여 obj에 객체를 생성해줍니다.

그리고 소멸자에 꼭 C++에서 만든 DeleteTestClass()를 이용하여 동적할당을 해제해줍니다.

 

public void SetBool(bool data) { SetBool(obj, data); }
public void SetInt(int data) { SetInt(obj, data); }

public bool GetBool() { return GetBool(obj); }
public int GetInt() { return GetInt(obj); }

 

TestClass의 함수들을 만들어주고 return으로 C++ 의 함수들을 다시 재호출하여 TestClass 함수만 사용해도 C++ 함수들을 사용할 수 있도록 만들어줍니다.


클래스 테스트

 

전체 코드

using System;
using System.Runtime.InteropServices;

namespace DLLTest
{
	class TestClass
	{
		[DllImport("D:\\C_Project\\ctest\\x64\\Release\\ctest.dll", CallingConvention = CallingConvention.Cdecl)]
		static private extern IntPtr CreateTestClass();

		[DllImport("D:\\C_Project\\ctest\\x64\\Release\\ctest.dll", CallingConvention = CallingConvention.Cdecl)]
		static private extern void SetBool(IntPtr obj, bool data);

		[DllImport("D:\\C_Project\\ctest\\x64\\Release\\ctest.dll", CallingConvention = CallingConvention.Cdecl)]
		static private extern void SetInt(IntPtr obj, int data);

		[DllImport("D:\\C_Project\\ctest\\x64\\Release\\ctest.dll", CallingConvention = CallingConvention.Cdecl)]
		static private extern bool GetBool(IntPtr obj);

		[DllImport("D:\\C_Project\\ctest\\x64\\Release\\ctest.dll", CallingConvention = CallingConvention.Cdecl)]
		static private extern int GetInt(IntPtr obj);

		[DllImport("D:\\C_Project\\ctest\\x64\\Release\\ctest.dll", CallingConvention = CallingConvention.Cdecl)]
		static private extern void DeleteTestClass(IntPtr obj);

		private IntPtr obj;

		public TestClass()
		{
			obj = CreateTestClass();
		}

		~TestClass()
		{
			DeleteTestClass(obj);
		}

		public void SetBool(bool data) { SetBool(obj, data); }
		public void SetInt(int data) { SetInt(obj, data); }

		public bool GetBool() { return GetBool(obj); }
		public int GetInt() { return GetInt(obj); }

	}

	class test
	{
		static void Main(string[] args)
		{
			TestClass lib = new TestClass();

			lib.SetBool(true);
			lib.SetInt(200);

			Console.WriteLine("[GetBool] " + lib.GetBool());
			Console.WriteLine("[GetInt] " + lib.GetInt());
		}
	}
}

 

이제 우리가 아는 클래스 형태로 C++의 DLL를 사용할 수 있습니다.

 

실행 결과


마무리

 

추가로 C++ 문자열을 C#에서 쓰는게 조금 복잡해서 따로 포스팅을 하였습니다.

궁금하신 분들은 아래 링크에서 확인 할 수 있습니다!

 

https://rurustory.com/1

 

[C#] 다양한 방법으로 C++ DLL String 사용하기

다양한 방법으로 C++ DLL String 사용하기 C#에서 C++로 문자열을 전달을 해줄때 자동으로 데이터를 맞춰주지만 C++에서 C#으로 문자열을 전달 할때는 수동으로 데이터를 맞춰야 합니다. 지금부터 다

rurustory.com

 

잘못된 점이 있거나 궁금한 점이 있다면 언제든지 문의해주시기 바랍니다!

728x90
반응형

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

[C#] 다양한 방법으로 C++ DLL String 사용하기  (0) 2024.02.21

 

C++ 클래스 기본적인 사용법

객체지향 언어인 C++의 클래스 사용법에 대해 알아봅시다.


접근 제어 지시자

 

public 어디서든 접근이 가능한 접근 제어 지시자이며 내부, 외부코드에서 모두 접근이 가능합니다.
private 선언한 클래스 내부에서만 접근이 가능한 접근 제어 지시자이며 외부에서 함부로 사용을 못하게 할때 사용합니다.
protected 기본적으로 private 역할을 하며 추가적으로 상속 받은 클래스에서도 접근이 가능한 접근 제어 지시자입니다.

 

 

기본적인 클래스 모양

 

class 클래스 이름
{
접근 제어 지시자:
    멤버변수
    멤버함수
};

클래스 선언부와 구현부

 

클래스 선언부: 클래스의 모양을 정의하는 곳이며 보통 헤더파일(.h파일)에 많이 정의합니다.

class TestClass
{
private:
	string stringTest;
    
public:
	void SetString(string data);
};

 

클래스 구현부: 클래스 선언부에서 정의한 함수들을 실제로 구현하는 곳입니다.

void TestClass::SetString(string data)
{
	cout << "[SetString] " << data << endl;
	stringTest = data;
}

생성자와 소멸자

 

생성자: 클래스 객체를 생성할때 자동으로 호출되는 함수 입니다. 사용자가 따로 코드작성을 하지 않으면 컴파일러가 알아

 

생성자 선언부

class TestClass 
{
public:
	TestClass();
};

 

생성자 구현부

TestClass::TestClass() 
{
	cout << "Init TestClass!!" << endl;
}

 

소멸자: 생성자와 반대로 클래스 객체가 소멸할때 자동으로 호출되는 함수 입니다. 생성자와 마찬가지로 사용자가 따로  코드작성을 하지 않으면 컴파일러가 알아서 아무런기능이 없는 함수로 만들어 실행합니다.

 

소멸자 선언부

class TestClass 
{
public:
	~TestClass();
};

 

소멸자 구현부

TestClass::~TestClass() 
{
	cout << "End TestClass!!" << endl;
}

클래스 객체 생성 및 사용

 

이제 앞에서 생성한 클래스로 객체를 만들어 사용하는 방법을 알아보겠습니다.

void main() 
{
	/* TestClass 클래스를 obj 이름으로 객체 생성 */
	TestClass obj = TestClass();

	/* 객체 함수 호출 */
	obj.SetString("Ruru TestString");
}

전체 예제 코드

 

헤더파일(.h파일)

#include <iostream>
using std::cout;
using std::endl;
#include <string>
using std::string;

class TestClass 
{
private:
	string stringTest;
	bool boolTest;
	int intTest;

public:
	TestClass();
	~TestClass();

	void SetString(string data);
	void SetBool(bool data);
	void SetInt(int data);

	string GetString();
	bool GetBool();
	int GetInt();
};

.

cpp파일

#include "ctest.h"

TestClass::TestClass() 
{
	cout << "Init TestClass!!" << endl;
}
TestClass::~TestClass() 
{
	cout << "End TestClass!!" << endl;
}

void TestClass::SetString(string data) 
{
	cout << "[SetString] " << data << endl;
	stringTest = data;
}
void TestClass::SetBool(bool data) 
{
	cout << "[SetBool] " << data << endl;
	boolTest = data;
}
void TestClass::SetInt(int data) 
{
	cout << "[SetInt] " << data << endl;
	intTest = data;
}

string TestClass::GetString() 
{
	return stringTest;
}
bool TestClass::GetBool() 
{
	return boolTest;
}
int TestClass::GetInt() 
{
	return intTest;
}

void main() 
{
	/* TestClass 클래스를 obj 이름으로 객체 생성 */
	TestClass obj = TestClass();

	/* 객체 함수 호출 */
	obj.SetString("Ruru TestString");
	obj.SetBool(true);
	obj.SetInt(200);
    
	cout << "[GetString] " << obj.GetString() << endl;
	cout << "[GetBool] " << obj.GetBool() << endl;
	cout << "[GetInt] " << obj.GetInt() << endl;
}

 

마무리

 

이상 C++ 클래스 기본적인 사용법에 대해 알아보았습니다.

잘못된 점이 있거나 궁금한 점이 있다면 언제든지 문의해주시기 바랍니다!

 

728x90
반응형

+ Recent posts