이미 작성되어 있는 C++ 의 코드를 C# 에서 사용하기 위해서는 DLL 라이브러리를 만들고, 이를 C# 에서 import를 해서
사용할 수 있다.
기본적으로 이미 라이브러리로 만들어져 배포되어 있던 것을 사용하려고 할 때에는 별 생각 없이 그에 맞춰서 하려고 했지만, 내가 처음부터 dll 로 라이브러리를 만들고 이를 사용하려고 할때, 워낙 방법이 다양하다 보니..
정확한 방법은 모르겠지만, 우선 나만의 format을 만들면 좋을 듯 하다.
하려고 할 때마다 늘 헷갈리고, 새로운 문제에 걸려서 힘들어해서.. 이를 정리하고자 한다.
우선 Interop에 대한 기본 방법에 대해서 먼저 익혀 두자.
참고 : http://ccambo.blogspot.kr/2013/01/c-interop-c-c-api.html
C, C++은 Native 코드로 unmanaged code 이며, .Net은 Managed code로 한다.
C (관리되지 않는 코드) |
C# (관리되는 코드) |
HANDLE, void* 또는 일반 pointer |
IntPtr |
BYTE, unsigned char |
Byte |
short |
Short |
WORD, unsigned short |
Ushort |
int |
int |
UINT, unsigned int |
uint |
long |
int |
BOOL, long |
int |
DWORD, unsigned long |
uint |
char |
char |
LPSTR, char* |
string 또는 StringBuilder |
LPCSTR, const char* |
string 또는 StringBuilder |
BSTR |
string |
float |
float |
double |
double |
HRESULT |
int |
VARIANT |
object |
DLL 데이터 입력하기
dll 함수에서 매개변수로 입력데이터를 원하는 경우에는 위의 표를 참고하여 매치되는 자료형을 사용하여 동일하게 입력하면 된다. 단, c에서는 struct 를 많이 사용하는데 이를 unmanaged code로 변환하기 위해서는
struct 를 정의하고 StructLayout 속성을 선언하여 사용이 가능하도록 해야한다.
StructLayout 관련해서는 위의 참고 URL에 잘 설명되어 있다.
API DLL을 만들때에 배열과 포인터는 같은 형식으로 인식하여, 오버로드가 안된다는 컴파일 에러가 발생한다.
따라서, 내부 구조적으로 포인터와 배열에 대한 Marshal 의 혼용이 가능하다.
매개변수에서 배열 또는 포인터를 요구 할 경우, 둘간의 데이터 크기만 약속되어 있다면 C#에서 배열을 쓰거나 또는 IntPtr를 사용한다.
DLL내 참조 데이터 입력하기 (C# 메모리 할당)
dll 을 사용하면서 가장 어려운 부분이 pointer와 & 주소참조자 그리고 배열 이였다.
이에 대한 데이터를 사용하기 위해서는 IntPtr 또는 ref를 사용하여야 하는데.. 사용하면서 여러차례의 디버깅을 해야만 가능하였다. 이는 dll 내부의 코드가 어떻게 구성되어 있는냐에 따라 차이가 발생된다고 생각된다.
DLL내 참조 데이터 입력하기 (DLL내부 메모리 할당)
DLL 내부에서 메모리 할당이 되는 코드는 다음과 같은 형식으로 매개변수를 받는다
메모리 할당을 받을 변수의 참조를 변수로 받는 구조로 되어 있다.
OutputVectorWithInitDoublePtrRef(double*& v)
OutputVectorWithInitStructPtrRef(Vector*& v)
전체적으로 자세한 설명을 적는것이 너무 버거워서..
c++과 c# 두 예제 프로젝트를 정리하였다.
전체적으로 내가 생각하는 조합들을 만들었으나, 구지 필요하지 않는 조합들도 있으므로 상황에 맞게 적절한 타입의 형태로 사용을 하면 된다.
c++ 사용된 데이터 타입은 double, double[], Vector(double을 갖는 struct), VectorArr(double[]를 갖는 strcut) 이 있다.
c# 구현에선는 해당 타입에 대응되는 기본자료형 타입과 구조체 타입을 모두 사용 시도하였다..
역시.. 말보다는 코드로 보는게 좋을 듯..
Richard_InteropLibraryTest.zip