Post List

2015년 8월 11일 화요일

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

MFC Extension DLL은 MFC에서 class를 DLL로 분리하여서 사용할 때 생성하는 DLL입니다.
MFC Extension DLL (확장 DLL)은 MFC안에서만 사용이 가능합니다.
그래서 C#같이 외부에서 사용하려면 중간에 Regular DLL을 만들어서 필요한 정보를 전달 하도록 구현하여야 합니다.

먼저 Regular DLL과 C#을 연동한 실습 Posting 을 진행 한 후에 아래 과정을 진행해 주시기 바랍니다.

http://devluna.blogspot.kr/2015/08/mfc-dll-c.html

위 Posting 대로 먼저 진행해 주세요.

1. MFC Extension DLL 생성

MFC DLL Project 로 이름은 ExtensionDll로 생성합니다.


다른 옵션은 모두 그대로 두고 MFC Extension DLL 을 선택한 뒤 Finish 버튼을 눌러서 생성합니다.



Project 의 Properties로 가셔서 CharacterSet을 Multibyte로 설정해주세요.

Solution Explorer에서 해당 Project에서 마우스 우 클릭 하신 뒤 추가 -> Class 를 선택하셔서 CMember 라는 Class를 생성합니다.
그래고 아래 내용으로 CMember.cpp 파일과 CMember.h 파일을 작성합니다.

* CMember.h

#pragma once
​class AFX_EXT_CLASS CMember : public CObject
​{
​public:
     CMember();
     ~CMember();
​
     void SetName(CString p_sName);
     void SetAge(int p_nAge);
     CString GetName();
     int GetAge();
     CString Introduce();
​
​private:
     CString m_sName = _T("");
     int              m_nAge = 0;
​};

 * CMember.cpp

#include "stdafx.h"
​#include "Member.h"
​
​CMember::CMember() ​{}
​CMember::~CMember() {}
​
​void CMember::SetName(CString p_sName) ​{ m_sName = p_sName; }
​void CMember::SetAge(int p_nAge) ​{ m_nAge = p_nAge; }
​CString CMember::GetName() { return m_sName; }
​int CMember::GetAge() { return m_nAge; }

​CString CMember::Introduce()
​{
     CString hello;
     hello.Format(_T("안녕하세요. 제 이름은 %s 이구요. 나이는 %d세 입니다. 앞으로 잘 부탁드리겠습니다." ), m_sName, m_nAge);
     return hello;
​}

간단하게 설명드리자면 AFX_EXT_CLASS 라는 키워드는 _AFXEXT가 선언된 Project 에서는 AFX_CLASS_EXPORT로 정의되며, 다른 Project에서는 AFX_CLASS_IMPORT 로 정의 됩니다.

Release / Win32 모드로 Build 합니다.

2. RegularDll 수정

Solution Explorer에서 Project 명에 마우스 우클릭 하셔서 Properties로 이동해 주세요.

Linker -> Input -> Additional Dependencies 에 ExtensionDll.lib 를 입력해주세요.
만약 Link시 해당 lib 파일을 못찾는 다면 lib 디렉토리를 추가해주면됩니다.
위 실습대로 그대로 따라하셨다면 아래 설정 대로 하면 됩니다.
Linker -> General -> Additional Library Directories 에 ../Release 를 입력해주세요.

RegularDll.cpp 파일에 가셔서 아래 내용을 추가해주세요.
당연히 include 부분은 파일 가장 위에, 함수선언은 파일 아랫쪽으로 해주세요.

#include "../ExtensionDll/Member.h"
​
​extern "C" __declspec(dllexport) LPCTSTR GetIntroduce(TCHAR* p_cName, int p_nAge)
​{
     CString sName;
     sName.Format(_T("%s"), p_cName);
​
     CMember M;
     M.SetName(sName);
     M.SetAge(p_nAge);
​
     return (LPCTSTR)M.Introduce();
​}

이제 Build 를 하여 정상적으로 완료되면

ExtensionDll.dll , RegularDll.dll 파일 2개를 복사해서 C# Project의 실행 폴더로 복사합니다.

3. 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());
       }

        [DllImport("RegularDll.dll")]
        public static extern IntPtr GetIntroduce(char[] c, int i);

        public static string GetIntroduce(string P_sName, int p_nAge)
       {
            return Marshal.PtrToStringAnsi(GetIntroduce(P_sName.ToCharArray(), p_nAge));
       }

        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} ", a, b);

            string intro = GetIntroduce(s, n);
            Console.WriteLine("{0}", intro);​
       }
    }
​}

이제 실행하시면 결과를 확인 할 수 있습니다.

댓글 없음:

댓글 쓰기