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로 가셔서 CharacterSetMultibyte로 설정해주세요.

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[] cint i);

        public static string GetIntroduce(string P_sNameint 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} "ab);

            string intro = GetIntroduce(sn);
            Console.WriteLine("{0}"intro);
       }
    }
}

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

댓글 없음:

댓글 쓰기