Visual Studio Community 2022에서 DLL 만든 후 Excel에서 사용하기

예전 Visual Studio 2008에서 Simple DLL 만든 후 Excel에서 사용하기 글을 통해 DLL 생성 후 엑셀에서 Declare 문을 통해 잘 사용했었다.

그러나!!!

당시 사용하던 Windows OS는 Windows XP, 그것도 32bit OS 이었고 Office 역시 32bit 버전이 대세였으나 현재는 Windows 10 64bit에 Office 역시 64bit가 대세를 형성하고 있다. 1

이와 같은 상황에서 예전 글을 참고해서, 그것도 10여 년 전 버전의 Visual Studio 2008 버전으로 DLL을 만들어 2022년 현재의 Windows 11 64bit + Office 2016 64bit 조합에 들이대기 영 껄쩍지근하던 차에 아래의 글을 발견하고 차례로 적용하여 성공한 기억을 잊어 먹지 않기 위해 글로 남긴다.

참고로 본인은 본 글 제목에서처럼 Visual Studio Community 2022 버전으로 시도했으니 참고하기를. 아, 또 하나는 상기 글을 작성한 저자가 아래와 같은 주의사항을 강한 늬앙스로 명기하고 있으니 이 역시 참고하기를.

Note: Be sure to change the path after Lib to the location of .dll on your own computer.

Above we define a function get_square_cpp which exposes our .dll file’s get_square function. Notice that we pass the argument by reference, as our C++ code expects a pointer. We then define a wrapper function named get_square which ensures that any data passed to our get_square_cpp is the expected “double” data type. Using get_square_cpp directly without the help of the explicitly typed parameters of the wrapper function can result in data being incorrectly marshalled to our C++ function, causing Excel to crash.

본인이 시도하여 성공한 순서대로 적고자 한다.

  1. 프로그램을 시작하여 ‘새 프로젝트 만들기(N)‘ 클릭
  2. 새 프로젝트 만들기‘ 창 상단 검색 바에서 ‘라이브러리‘ 입력 후 나타나는 목록 중 ‘DLL(동적 연결 라이브러리)‘ 선택 후 ‘다음‘ 클릭
  3. 새 프로젝트 구성‘ 창 내 ‘프로젝트 이름(J)‘에 ‘MyUtil‘ 입력 후 ‘만들기(C)‘ 클릭
  4. 메인 메뉴에서 ‘프로젝트(P)‘ ⇒ ‘새 항목 추가(W)…‘ 클릭
  5. 새 항목 추가‘ 창에서 ‘헤더 파일(.h)‘ 선택하고 하단 ‘이름(N)‘ 입력란에 ‘MyUtil.h‘ 입력 후 ‘추가(A)‘ 클릭
  6. 메인 창 ‘MyUtil.h‘ 탭 안에 아래 내용 입력
    // MyUtil.h - 함수들에 대한 선언 포함
    #pragma once
    
    #ifdef MYUTIL_EXPORTS
    #define MYUTIL_API __declspec(dllexport)
    #else
    #define MYUTIL_API __declspec(dllimport)
    #endif
    
    extern "C" MYUTIL_API double GetSquare(double* x);
    extern "C" MYUTIL_API double MyX(double* a, double* b);

  7. 우측 ‘솔루션 탐색기‘ 창에서 마우스 우클릭으로 ‘소스 파일‘ 클릭 후 ‘추가‘ ⇒ ‘새 항목(W)…‘ 클릭
  8. 새 항목 추가‘ 창에서 ‘C++ 파일(.cpp)‘ 선택하고 하단 ‘이름(N)‘ 입력란에 ‘MyUtil.cpp‘ 입력 후 ‘추가(A)‘ 클릭
  9. 메인 창 ‘MyUtil.cpp‘ 탭 안에 아래 내용 입력
    // MyUtil.cpp : DLL로 내보낸 (exported) 함수 정의.
    #include "pch.h" // use stdafx.h in Visual Studio 2017 and earlier
    #include "MyUtil.h"
    #include <cmath>
    
    double WINAPI GetSquare(double* x)
    {
        return *x * *x;
    }
    
    double WINAPI MyX(double* a, double* b)
    {
        if (*a > *b)
            return pow(*a, *b);
        else
            return pow(*b, *a);
    }

  10. 메인 메뉴에서 ‘빌드‘ ⇒ ‘솔루션 빌드(B)‘ 클릭
  11. 상단 도구 모음에서 ‘x64‘ 확인 후 하단 ‘출력‘ 창에서 빌드 성공 메시지 확인
  12. 엑셀을 시작하여 ‘MyUtil.xlsb’란 새 이름으로 저장하고 ‘ALT + F11’ 이용하여 나타난 Microsoft Visual Basic for Application 창에 아래 내용을 입력 2
    Option Explicit
    	
    ' Win64는 64비트 오피스인지 판별하는 상수
    ' VBA7은 오피스 2010 이상인지 판별하는 상수
    #If Win64 Then
        Private Declare PtrSafe Function GetSquareCpp Lib "C:\Users\Kiin\source\repos\MyUtil\x64\Debug\MyUtil.dll" _
            Alias "GetSquare" (ByRef Arg As Double) As Double
    
        Private Declare PtrSafe Function MyXCpp Lib "C:\Users\Kiin\source\repos\MyUtil\x64\Debug\MyUtil.dll" _
            Alias "MyX" (ByRef Arg1 As Double, ByRef Arg2 As Double) As Double
    #Else ' x86으로 Build한 DLL 선언
        Private Declare Function GetSquareCpp Lib "C:\Users\Kiin\source\repos\MyUtil\x86\Debug\MyUtil.dll" _
            Alias "GetSquare" (ByRef Arg As Double) As Double
    
        Private Declare Function MyXCpp Lib "C:\Users\Kiin\source\repos\MyUtil\x86\Debug\MyUtil.dll" _
            Alias "MyX" (ByRef Arg1 As Double, ByRef Arg2 As Double) As Double
    #End If
    
    ' ByRef가 기본이나 하나의 셀에 있는 값을 인수로 받기 때문에 명확하게 하기 위해 ByVal 사용
    Public Function GetSquare(ByVal x As Double) As Double
        GetSquare = GetSquareCpp(x)
    End Function
    
    ' ByRef가 기본이나 하나의 셀에 있는 값을 각각 인수로 받기 때문에 명확하게 하기 위해 ByVal 사용
    Public Function MyX(ByVal Arg1 As Double, ByVal Arg2 As Double) As Double
        MyX = MyXCpp(Arg1, Arg2)
    End Function
    
    Sub tmp()
        MsgBox GetSquare(0.2)
        MsgBox MyX(0.8, 0.2)
    End Sub

  13. 실제로 적용하여 아무런 문제가 없는 것을 확인!!!

예전과는 다른 방법으로 엑셀에서 사용하려는 DLL을 생성했으며 또한 과거 종종 DLL 사용하던 엑셀이 Crash로 죽던 경우가 본 방법을 통해 생성한 DLL 사용 시 아직까지는 발생하지 않고 있다.

Footnotes

  1. 본인 주변을 돌아봤을 때를 전제로 한 판단이다. 아니면 말고.
  2. 캡처 이미지 상으로 붉은 부분이 있어서 오류라고 착각할 수도 있으나 실제 사용하는 데에는 전혀 지장을 주지 않는다.

댓글 남기기

이 사이트는 스팸을 줄이는 아키스밋을 사용합니다. 댓글이 어떻게 처리되는지 알아보십시오.