Post List

2015년 8월 11일 화요일

MFC로 만든 DLL을 C#에서 사용하기 (초간단 실습)

MFC 에서 만든 DLL을 C#에서 사용하는 방법에 대해서 설명드리겠습니다.
간단하게 따라해볼 수 있도록 실습 위주로 설명 드리겠습니다.

MFC 에서 생성한 DLL을 C#에서 사용할려면 MFC Extend DLL처럼 Class 를 Export 하는 형식의 DLL은 사용이 안됩니다.
C-Style 의 Function 을 Export 하는 DLL만 C#에서 사용이 가능합니다.
MFC Extend DLL을 C#에서 사용할려면 별도의 DLL 파일을 추가로 하나 만든 뒤
그 DLL에서 MFC Extend DLL의 기능들을 활용하여 Function 형태로 작성 한 뒤
C#에서 해당 DLL을 사용하는 방법으로 구현하시면 됩니다.

1. MFC DLL Project 생성

MFC DLL 로 Project를 생성하고 이름은 RegularDLL 로 했습니다.
Project의 세부 속성은 변경하지 않고 바로 Finish를 눌러줍니다.



Solution Explorer에서 Project 명에서 마우스 우클릭하셔서 Properties로 가신 후 CharactersetMultibyte로 바꿔주세요.
Unicode로 한 경우 C#에서 기본적으로 전달하는 문자열이 Multibyte이기 때문에 Test할때 깨집니다.
C#에서도 동일하게 Unicode로 설정해서 전달하면 되지만, 일단은 간단한 실습이니 그냥 Multibyte로 하겠습니다.



RegularDLL.cpp 파일을 열어서 가장 아래쪽으로 이동한 뒤 아래 Code를 추가해 주세요.

int n = 0;
CString s;

extern "C" __declspec(dllexport) void SetInt(int p_n)
{
    n = p_n;
}

extern "C" __declspec(dllexport) int GetInt()
{
     return n;
}

extern "C" __declspec(dllexport) void SetString(TCHAR* p_ca)
{
     s.Format(_T("%s"), p_ca);
}

extern "C" __declspec(dllexport) LPCTSTR GetString()
{
     return (LPCTSTR)s;
}

그리고 Release Win32 로 Build 를 진행합니다.
생성된 RegularDLL.dll 파일을 나중에 C#의 실행파일 폴더로 복사를 해야하니 잘 보관해 둡니다.

2. C#용 Test Console Project 생성

새 Project 추가를 하셔서 C# -> Console Application Program을 추가하세요.
CSExec 란 이름으로 생성하였습니다.



Program.cs 파일이 연 뒤 아래와 같이 작성해주세요.

using System;
using System.Runtime.InteropServices;

namespace CSExec
{
    class Program
    {
        [DllImport("RegularDll.dll")]
        public static extern void SetInt(int p);

        [DllImport("RegularDll.dll")]
        public static extern int GetInt();

        [DllImport("RegularDll.dll")]
        public static extern void SetString(char[] p);

        [DllImport("RegularDll.dll")]
        public static extern IntPtr GetString();

        public static string _GetString()
        {
            return Marshal.PtrToStringAnsi(GetString());
        }

        public static void SetString(string p)
        {
            SetString(p.ToCharArray());
        }

        static void Main(string[] args)
        {
            int n = 10;
            SetInt(n);
            int a = GetInt();

            string s = "Luna";
            SetString(s);
            string b = _GetString();
            Console.WriteLine(" {0} : {1} "ab);
        }
    }
}

문자열 같은 경우 StringBuiler 를 이용해서 전달받는 방법도 소개가 많이 되었던데,
잘 되지 않더라구요. 가장 확실한 것은 IntPtr로 전달받은뒤 Marshal을 이용해서 Convert 하는 방법일듯 합니다.
현재 MFC도 Multibyte 로 Project 설정을 하여서 PtrToStringAnsi( ) 를 사용하였습니다.
상황에 따라 PtrToStringAuto( )PtrToStringUni( ) 를 활용하시면 됩니다.
Build 를 하뒤 생성된 결과물 폴더에 MFC로 작성한 DLL 파일을 복사 한 뒤에 실행을 하시면 정상적으로 동작하는 것을 확인 할 수 있습니다.

댓글 없음:

댓글 쓰기