C#에서 C++ DLL 선언

C#에서 C++ DLL를 사용하려면 extern 키워드를 이용해서 C++ DLL의 함수를 선언해 줘야 한다. 선언 하는 방법은 아래 코드와 같다. 만일 C#에서 pointer(*)를 넘겨야 하는 경우가 있다면 unsafe 키워드를 추가로 붙여준다.

// DllImport에 지정되는 이름은 C++ DLL의 이름과 경로를 의미한다.
[DllImport("Test.dll")]
static extern int Sum(int num1, int num2);

// *를 사용하고 있으므로 unsafe 키워드를 붙여 준다.
[DllImport("Test.dll")]
unsafe static extern bool Detect(byte* source);

기본 타입 전달하고 return 받기

int나 double 같은 기본 타입에 대해서는 알아서 변환이 되므로 일반적으로 코드를 작성하는 것처럼 사용하면 된다.

// C++ 코드
int AddInt(const int val1, const int val2)
{
	return val1 + val2;
}

double MultiplyDouble(const double val1, const double val2)
{
	return val1 * val2;
}
// C# 코드
int numInt = AddInt(val1: 1, val2: 2);  // 결과는 3
double numDouble = MultiplyDouble(val1: 2d, val2: 0.5d);  // 결과는 1

구조체 전달하고 return 받기

구조체는 C#과 C++에서 형식과 그 순서를 맞춰야 한다는 것만 제외하면 사용하는 법은 기본 타입과 동일하다. 우선 C++과 C#의 구조체는 다음과 같이 맞추면 된다.

// C++ 코드
struct StructSample
{
public:
	StructSample(int numInt, double numDouble) : numInt(numInt), numDouble(numDouble) { }

	int GetNumInt() const { return this->numInt; }
	int GetNumDouble() const { return this->numDouble; }

private:
	int numInt;
	double numDouble;
};
// C# 코드
[StructLayout(LayoutKind.Sequential)]
struct StructSample
{
    public StructSample(int numInt, double numDouble)
    {
        this.NumInt = numInt;
        this.NumDouble = numDouble;
    }

    public int NumInt { get; private set; }
    public double NumDouble { get; private set; }
};

C#에서 구조체에 특성으로 LayoutKind를 Sequential로 놓고 C++과 C#의 구조체 내부 순서를 맞추면 문제 없이 사용 가능하다. —class로는 안 된다.

위의 예시는 일부러 생성자와 C++에서 Get 함수, C#에서 Property를 구성하였는데, 이렇게 해도 동작 가능하다는 것을 보여주기 위해 한 것이다.

// C++ 코드
StructSample MultiplyStructure(const StructSample& input)
{
	return StructSample(input.GetNumInt() * 2, input.GetNumDouble() * 2.0);
}
// C# 코드
StructSample input = new StructSample(numInt: 1, numDouble: 2d);
StructSample output = NativeMethod.MultiplyStructure(input: input);  // 결과는 2, 4

C#에서 C++로 string 전달하기

C#과 C++의 string은 이름은 같지만 그 구현은 전혀 다른 것이다. 그러나 둘 다 char로 된 배열이라는 점이 같으므로 C++의 인자 쪽을 char* 타입으로 하여 C#의 string을 C++로 전달할 수 있다.

그렇게 전달 받은 char*를 C++ 내에서는 string 타입으로 변환하여 사용하면 된다.

// C++ 코드
int AddStringLength(const char* val1, const char* val2)
{
	string str1(val1);
	string str2(val2);

	return str1.size() + str2.size();
}