ํด๋น ๊ฒ์๊ธ์ ์๋ ๊ฐ๋ฐํ๊ฒฝ์ ์ฌ์ฉํ์ฌ ์์ฑ๋จ
IDE : VisualStudio 2022
Framework : .NET 7.0
Language : C# 11
1. ๋ง์ฌ๋ง (Marshalling) & C++ DLL
- ๋ง์ฌ๋ง๊ณผ C++ DLL ์์ฑ์ ๋ํ ๋ด์ฉ์ ์๋ ๊ฒ์๊ธ์ ์ฐธ๊ณ
[C#] ์ง๋ ฌํ&๋ง์ฌ๋ง
1. ์ฉ์ด ์ ๋ฆฌ Managed Code : .NET ๋๋ C# ์ปดํ์ผ๋ฌ๊ฐ ์์ฑํ ์ฝ๋๋ฅผ ์๋ฏธ, ์ปดํ์ผ๋ฌ๋ ์ค๊ฐ ์ธ์ด(Intermediate Language, IL)์ฝ๋๋ฅผ ์์ฑํ๊ณ CLR(Common Language Runtime) ํ๊ฒฝ์์ ๊ธฐ๊ณ ์ธ์ด ์์ฑ Unmanaged Code : ์ปดํ
ssvip.tistory.com
[C++] ๋์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ(DLL) ๋ง๋ค๊ธฐ
ํด๋น ๊ฒ์๊ธ์ ์๋ ๊ฐ๋ฐํ๊ฒฝ์ ์ฌ์ฉํ์ฌ ์์ฑ๋จ IDE : Visual Studio 2022 Language : C++ 14 1. ๋์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ ๋์ ๋ผ์ด๋ธ๋ฌ๋ฆฌ์ ๋ํ ๋ด์ฉ์ ์๋ ๊ฒ์๊ธ์ ์ฐธ๊ณ [C++] ๋ผ์ด๋ธ๋ฌ๋ฆฌ ์ข ๋ฅ 1. ์ฉ์ด์ ๋ฆฌ ํ์ค
ssvip.tistory.com
2. C#์์ C++ DLL ์ฌ์ฉ
- .NET์์๋ DllImport ๋ช ๋ น์ด๋ฅผ ์ฌ์ฉํ์ฌ DLL์ ์ฐธ์กฐํ ์ ์๋ค.
- ์ธ๋ถ(DLL)์์ ์ ์๋ ํจ์๋ extern ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ C# ๋ด๋ถ์ ์ ์ธํ ์ ์๋ค.
2.1 DllImport
- .NET์์ Unmanaged Code์ธ DLL์ ์ ์๋ ํจ์์ ์ง์ ์ ์ ์ ์ธํ ๋ ์ฌ์ฉ
- System.Runtime.InteropServices ๋ค์์คํ์ด์ค์ DllImportAttribute ํด๋์ค๋ก ์ ์
- ๋น๊ด๋ฆฌ ์ฝ๋์์ ๊ตฌํ๋ ํจ์๋ฅผ ํธ์ถํ๋๋ฐ ํ์ํ ํธ์ถ ๊ท์น์ ์ง์ ํ๊ธฐ ์ํด CallingConvention์ ์ง์ (2.2 ์ฐธ๊ณ )
[DllImport("Module.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern void DLLMethod();
- DllImportAttribute ์ ์
/*
* DllImportAttribute ์ ์
*/
namespace System.Runtime.InteropServices
{
[AttributeUsage(AttributeTargets.Method, Inherited = false)]
public sealed class DllImportAttribute : Attribute
{
public DllImportAttribute(string dllName)
{
Value = dllName;
}
public string Value { get; }
public string? EntryPoint;
public CharSet CharSet;
public bool SetLastError;
public bool ExactSpelling;
public CallingConvention CallingConvention;
public bool BestFitMapping;
public bool PreserveSig;
public bool ThrowOnUnmappableChar;
}
}
2.2 Calling Convention (ํจ์ ํธ์ถ ๊ท์ฝ)
- ํจ์ ํธ์ถ ๊ท์ฝ : ํธ์ถ์(Caller)์ ํผํธ์ถ์(Callee)๊ฐ์ ํจ์๋ฅผ ํธ์ถํ ๋ ์ ๋ฌ๋๋ ์ธ์์ ์์๋ ํจ์ ์ฌ์ฉ ํ ์คํ ์ ๋ฆฌ ๋ฑ์ ๋ํ ๊ท์ฝ
- ๋น๊ด๋ฆฌ ์ฝ๋์์ ๊ตฌํ๋ ๋ฉ์๋๋ฅผ ํธ์ถํ๋๋ฐ ํ์ํ ํธ์ถ ๊ท์น ์ง์
//
// ์์ฝ:
// Specifies the calling convention required to call methods implemented in unmanaged
// code.
public enum CallingConvention
{
//
// ์์ฝ:
// This member is not actually a calling convention, but instead uses the default
// platform calling convention. For example, on Windows x86 the default is System.Runtime.InteropServices.CallingConvention.StdCall
// and on Linux x86 it is System.Runtime.InteropServices.CallingConvention.Cdecl.
Winapi = 1,
//
// ์์ฝ:
// The caller cleans the stack. This enables calling functions with varargs, which
// makes it appropriate to use for methods that accept a variable number of parameters,
// such as Printf.
Cdecl = 2,
//
// ์์ฝ:
// The callee cleans the stack.
StdCall = 3,
//
// ์์ฝ:
// The first parameter is the this pointer and is stored in register ECX. Other
// parameters are pushed on the stack. This calling convention is used to call methods
// on classes exported from an unmanaged DLL.
ThisCall = 4,
//
// ์์ฝ:
// This calling convention is not supported.
FastCall = 5
}
2.3 extern
- ์ธ๋ถ์์ ๊ตฌํ๋ ๋ฉ์๋ ์ ์ธ์ extern ํค์๋๋ฅผ ์ฌ์ฉํ๋ค.
- Interop ์๋น์ค๋ฅผ ์ฌ์ฉํ์ฌ ๋น๊ด๋ฆฌ ์ฝ๋๋ฅผ ํธ์ถํ ๋, extern ํค์๋๋ DllImport ๋ช ๋ น์ด์ ํจ๊ป ์ฌ์ฉ๋๋ค. ์ด ๊ฒฝ์ฐ ๋ฉ์๋๋ฅผ static์ผ๋ก ์ ์ํด์ผ ํ๋ค.
- extern ํค์๋๊ฐ ํฌํจ๋ ๊ฒฝ์ฐ ๋ฉ์๋๊ฐ ์ธ๋ถ ๋ฉ์๋๋ก ๊ฐ์ฃผ๋๋ฉฐ ์ค์ ๊ตฌํ์ด ํฌํจ๋์ง ์๋๋ค.
// 1. extern ํค์๋๋ฅผ ์ฌ์ฉํ์ฌ Module.dll์ ์ ์๋ ๋ฉ์๋ ์ ์ธ
[DllImport("Module.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern void DLLMethod();
// 2. ์ ์๋ ๋ฉ์๋ ํธ์ถ
private static void Method()
{
DLLMethod(); // DLLMethod ํธ์ถ
}
3. ๋์์ธ
- ์๋ ์ด๋ฏธ์ง์ ๊ฐ์ด ์ปจํธ๋กค๋ฌ๋ค์ ๋ฐฐ์นํ๋ค.
4. ์ฝ๋ ์์ฑํ๊ธฐ
- 4.1 ~ 4.3์ ์ฐธ๊ณ ํ์ฌ DLL_Project.dll์ ํธ์ถํ๋ ์ฝ๋๋ฅผ ์์ฑํ๋ค.
- ํด๋น ์ฝ๋์์ ์ฌ์ฉํ DLL_Project.dll์ debug, release์ ์คํ ํ์ผ์ด ์์ฑ๋๋ ๊ฒฝ๋ก์ ์ฎ๊ฒจ๋๋ค.
4.1 DLL Class ์์ฑ
- DLL ์ ์ ์๋ ํจ์๋ฅผ ์ฌ์ฉํ ํด๋์ค๋ฅผ ์ ์ธํ๊ณ extern ํค์๋๋ฅผ ์ด์ฉํ์ฌ DLL ํจ์๋ค์ ์ ์ธํ๋ค.
public class DLL
{
[DllImport("DLL_Project.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern double Sum(double a, double b);
[DllImport("DLL_Project.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern double Sub(double a, double b);
[DllImport("DLL_Project.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern double Mul(double a, double b);
[DllImport("DLL_Project.dll", CallingConvention = CallingConvention.Cdecl)]
private static extern double Div(double a, double b);
public static double CalcSum(double a, double b)
{
double sum = Sum(a, b);
return sum;
}
public static double CalcSub(double a, double b)
{
double sum = Sub(a, b);
return sum;
}
public static double CalcMul(double a, double b)
{
double sum = Mul(a, b);
return sum;
}
public static double CalcDiv(double a, double b)
{
double sum = Div(a, b);
return sum;
}
}
4.2 DLL Class ํธ์ถ
- ๊ณ์ฐ ๋ฒํผ ํด๋ฆญํ๋ฉด DLL Class๋ฅผ ์ฌ์ฉํ์ฌ ์ ๋ ฅ๋ ์ซ์ 2๊ฐ๋ฅผ ์ฌ์น์ฐ์ฐํ๋ ๋ฉ์๋๋กค ํธ์ถํ๋ค.
private void btnCalc_Click(object sender, EventArgs e)
{
double number1 = Double.Parse(txtNumber1.Text.ToString());
double number2 = Double.Parse(txtNumber2.Text.ToString());
double sum = DLL.CalcSum(number1, number2);
double sub = DLL.CalcSub(number1, number2);
double mul = DLL.CalcMul(number1, number2);
double div = DLL.CalcDiv(number1, number2);
txtSum.Text = sum.ToString();
txtSub.Text = sub.ToString();
txtMul.Text = mul.ToString();
txtDiv.Text = div.ToString();
}
4.3 ์คํ๊ฒฐ๊ณผ
- ์คํ ๊ฒฐ๊ณผ๋ ์๋ ์ด๋ฏธ์ง์ ๊ฐ๋ค.
๋ง์ฌ๋ง(Marshalling) ์ง๋ ฌํ(Serialization) ์ฐจ์ด
๋ฏธ๊ตญ์ ์ฒ ์๋ Marshaling CS์์ ๋ง์ฌ๋ง(Marshalling)์ ํ์ผ๋ก ์ ์ฅํ๊ฑฐ๋ ๋คํธ์ํฌ ์ ์กํ๊ธฐ ์ํด์ ๊ฐ์ฒด์ ๋ฐ์ดํฐ ํฌ๋งท์ ์ ํฉํ ํํ๋ก ๋ณํํ์ฌ ๋ฉ๋ชจ๋ฆฌ์ ํํํ๋ ๊ณผ์ ์ ๋๋ค. ์ผ๋ฐ์ ์ผ๋ก ์ปดํจ
velog.io
c++ <-> c# Marshalling ์ฌ์ฉ๋ฒ
๋ชฉ์ C#์์ C++๋ก ๊ตฌํ๋ DLL์ ์ด์ฉํ๋ค.(๊ฐ์ธ์ ์ธ ๋ฉ๋ชจ์ด๋ ์ฐธ๊ณ ํ์ค ๋ถ๋ค ์ฐธ๊ณ ํ์ธ์) ์ ํ์ฌํญ์ผ๋ก๋ C++ DLL์ด ๋์ผ ๊ฒฝ๋ก์ ์์ด์ผํจ. ํฌ์คํธ์ DLL๋ช ์ KJK92.DLL๋ก ์ ์ 1. Default Marshalling (๊ธฐ๋ณธ)
kjk92.tistory.com
๊ธธ์ด๊ฐ ๊ณ ์ ๋์ง ์์ pointer array ๋ง์ฌ๋งํ๊ธฐ
C/C++ ์์ ์์ฑํ ์ฝ๋๋ฅผ C#์์ ์ฌ์ฉํ๊ธฐ ์ํ ์์ ์ ํ๋ ์ค, ๊ฐ๋ณ๊ธธ์ด ํฌ์ธํฐ ๋ฐฐ์ด์ ๋ํด ๋ณํํ๋ ๋ฐฉ๋ฒ์ ๋ํด ๊ณต์ ํฉ๋๋ค. ์ํ๋ก ๋ง๋ C ์ฝ๋๋ ์๋์ ๊ฐ์ต๋๋ค. typedef struct { char *name; int
inasie.tistory.com
๋ฌธ์์ด์ ๋ํ ๊ธฐ๋ณธ ๋ง์ฌ๋ง - .NET Framework
.NET์์ ์ธํฐํ์ด์ค, ํ๋ซํผ ํธ์ถ, ๊ตฌ์กฐ์ฒด ๋ฐ ๊ณ ์ ๊ธธ์ด ๋ฌธ์์ด ๋ฒํผ์ ๋ฌธ์์ด์ ๋ํ ๊ธฐ๋ณธ ๋ง์ฌ๋ง ๋์์ ๊ฒํ ํฉ๋๋ค.
learn.microsoft.com
C# - ๋ง์ฌ๋ง์ด๋? (Marshalling)
C#์์ ๋ง์ฌ๋ง์ด๋ ๋ฌด์์ด๋ฉฐ ์ ์ฌ์ฉํ๋ ๊ฒ์ผ๊น์?
hwanine.github.io
C#์ extern ํค์๋
์ค๋์ ๊ธฐ์ฌ์์๋ C#์์ extern ํค์๋์ ๊ธฐ๋ฅ์ ๋ฐฐ์๋๋ค.
www.delftstack.com
'๊ฐ๋ฐ๐ป > C#' ์นดํ ๊ณ ๋ฆฌ์ ๋ค๋ฅธ ๊ธ
[C#] Log #1 Log ์ ๋ฆฌ (0) | 2023.09.11 |
---|---|
[C#] ๋ฐฐํฌํ์ผ ๋ง๋ค๊ธฐ (Installer) (1) | 2023.08.06 |
[C#] ์ง๋ ฌํ&๋ง์ฌ๋ง (0) | 2023.07.01 |
[C#] TCP ์ฑํ ํ๋ก๊ทธ๋จ #2 Client ๊ตฌํ (0) | 2023.06.12 |
[C#] TCP ์ฑํ ํ๋ก๊ทธ๋จ #1 Server ๊ตฌํ (4) | 2023.06.11 |