본문 바로가기
프로그래밍 이야기/기타

[MATLAB] MATLAB 코드를 C/C++언어 환경에서 실행하기 - 2부 Visual Studio 설정 및 실행

by meticulousdev 2022. 6. 7.
반응형

- 개발환경

    - Windows 10
    - MATLAB 2016b (필수 툴박스: MATLAB Compiler SDK)
    - Visual Studio Community 2019

    - 더 이상 매트랩을 구매하지 않아서 MATLAB 2016b에서 진행된다는 점에 대해 양해 부탁드립니다.

 

1. MATLAB 환경 설정 및 package 생성

    본 글은 MATLAB을 통해서 생성된 dll, lib, h 파일을 활용하는 방법에 대한 글입니다. 이에 관한 내용을 아래의 링크를 확인해주시기 바랍니다.

https://meticulousdev.tistory.com/entry/MATLAB-MATLAB-코드를-CC언어-환경에서-실행하기-1부-MATLAB-환경-설정-및-package-생성?category=1072524 

 

[MATLAB] MATLAB 코드를 C/C++언어 환경에서 실행하기 - 1부 MATLAB 환경 설정 및 package 생성

- 개발환경 - Windows 10 - MATLAB 2016b (필수 툴박스: MATLAB Compiler SDK) - Visual Studio Community 2019 - 더 이상 매트랩을 구매하지 않아서 MATLAB 2016b에서 진행된다는 점에 대해 양해 부탁드립니다. 1..

meticulousdev.tistory.com

 

2. Visual Studio Community 2019 프로젝트 생성

    제일 먼저 할 일은 프로젝트 파일을 만들고 환경설정을 해주는 것입니다. New Project > Empty Project로 새로운 프로젝트를 먼저 생성해줍니다.

그리고 c확장자를 가지는 파일을 하나 생성해 줍니다. 저는 main.c로 만들었습니다. 우선은 안에 아무 코드가 작성되어 있지 않아도 됩니다. 그러고 나서 1부에서 생성한 파일들을 main.c 파일이 있는 동일한 폴더에 위치시킵니다.

 

 

3. 프로젝트 설정

    다음 단계는 프로젝트에서 설정을 잡아주는 것입니다.

 

1) 실행 환경에 맞게 플랫폼을 설정해줍니다. 저는 64 bit 시스템에서 작동시킬 것이기 때문에 x64로 잡았습니다. 그리고 프로젝트에 헤더 파일과 c언어 파일을 추가해줍니다. 저의 경우 add.h와 main.c 파일입니다.

 

2) C/C++ > General > Additional Include Directoreis에 MATLAB이 설치된 경로 상에서 extern\include의 경로를 추가합니다. MATLAB이 설치된 상태에서 테스트를 할 때는 첫 번째 경로를 입력해서 테스트를 해보시면 됩니다. 만약 매트랩이 설치되어 있지 않고 Runtime만 설치되어 있는 경우 두 번째 경로를 입력하시면 됩니다. 저는 매트랩이 설치되어 있지 않은 컴퓨터에서 Runtime을 호출하는 방식으로 테스트하였습니다.

(1) MATLAB이 설치된 경우 - C:\Program Files\MATLAB\R2016b\extern\include
(2) Runtime이 설치된 경우 - C:\Program Files\MATLAB\MATLAB Runtime\v91\extern\include

 

 

3) Linker > General > Additional Library Directoreis에 아래의 경로를 추가합니다. 

(1) MATLAB이 설치된 경우 - C:\Program Files\MATLAB\R2016b\extern\lib\win64\microsoft
(2) Runtime이 설치된 경우 - C:\Program Files\MATLAB\MATLAB Runtime\v91\extern\lib\win64\microsoft

 

4) Linker > Inputmclmcrrt.lib를 추가합니다.

이제 모든 설정이 끝났습니다.

 

4. 실행 코드

    먼저 add.h 파일을 간단하게 봐보겠습니다. 코드 제일 아래를 보면 mlfAdd 함수가 있습니다. 최종적으로 호출하게 될 함수입니다. 첫 번째 인자로 출력 변수의 수, 두 번째 인자로 출력 변수, 세 번째 그리고 네 번째 인자로 입력 변수가 입력됩니다. C Shared Library로 선택한 경우 함수에서 mxArray 데이터를 요구합니다. (만약, mwArray를 요구한다면 C++ Shared Library가 선택된 경우 입니다.)

add.h

...
extern LIB_add_C_API bool MW_CALL_CONV mlfAdd(int nargout, mxArray** c, mxArray* a, mxArray* b);
...

 

기본적인 호출 방법을 알았으니 main.c를 작성해보겠습니다. 전체 코드를 보여드리고 필요한 부분들을 설명하겠습니다.

#include <stdio.h>

#include "add.h"

#pragma comment(lib, "add.lib")

int main(void)
{
	printf("MATLAB to C/C++\n");

	if (!mclInitializeApplication(NULL, 0))
	{
		printf("mclInitializeApplication error\n");
		return -1;
	}

	if (!addInitialize())
	{
		printf("add lib error\n");
		return -1;
	}

	double a = 1.0;
	double b = 2.0;

	mxArray * ptr_a = mxCreateDoubleScalar(a);
	mxArray * ptr_b = mxCreateDoubleScalar(b);
	mxArray * ptr_c = NULL;

	mlfAdd(1, &ptr_c, ptr_a, ptr_b);

	double * c = mxGetPr(ptr_c);

	printf("%f + %f = %f\n", a, b, *c);

	mxDestroyArray(ptr_a);
	mxDestroyArray(ptr_b);
	mxDestroyArray(ptr_c);

	addTerminate();
	mclTerminateApplication();
	return 0;
}

 

1) 실행에 필요한 기본적은 헤더 파일들이 필요하기 때문에 아래와 같이 포함시킵니다. 그리고 생성된 lib 파일을 프로젝트에서 사용할 수 있게 해 줍니다.

#include <stdio.h>

#include "add.h"

#pragma comment(lib, "add.lib")

 

2) MATLAB 및 MATLAB에서 넘어온 함수가 정상 작동이 가능한지에 대한 코드를 추가합니다. 오류 발생 시 에러 메시지와 함께 프로그램을 종료합니다.

if (!mclInitializeApplication(NULL, 0))
{
    printf("mclInitializeApplication error\n");
    return -1;
}

if (!addInitialize())
{
    printf("add lib error\n");
    return -1;
}

 

3) 이제 입력할 값들을 정해줍니다. C언어의 데이터 형식을 그대로 사용할 수 없기 때문에 mxCreateDoubleScalar 함수를 이용해서 MATLAB에 전달해줄 수 있는 파일의 형태로 변경해줍니다. ptr_c 변수를 최종적으로 값이 저장될 변수이기 때문에 우선은 NULL을 할당해 둡니다. 그다음으로는 앞서 봤던바와 같이 mlfAdd 함수 호출을 위한 인자들을 모두 전달해줍니다. 끝으로 반환된 값을 mxGetPr함수를 통해서 C언어에서 사용 가능한 형태로 받아옵니다.

double a = 1.0;
double b = 2.0;

mxArray * ptr_a = mxCreateDoubleScalar(a);
mxArray * ptr_b = mxCreateDoubleScalar(b);
mxArray * ptr_c = NULL;

mlfAdd(1, &ptr_c, ptr_a, ptr_b);

double * c = mxGetPr(ptr_c);

 

4) 변수들의 사용이 끝나면 메모리 공간에서 제거하는 작업을 진행합니다. 뿐만 아니라 실행했던 함수와 MATLAB과 관련된 모든 것을 종료시켜(terminate) 줍니다. 

mxDestroyArray(ptr_a);
mxDestroyArray(ptr_b);
mxDestroyArray(ptr_c);

addTerminate();
mclTerminateApplication();

 

코드에 대한 설명은 끝났습니다. 이제 F5를 누르면 아래와 같이 매트랩으로 작성했던 코드가 C언어에서 동작하는 것을 보실 수 있습니다. 처음 코드를 실행시키기 까지 오랜 시간이 걸리기 때문에 코드가 돌아가는 동안 잠시 쉬고 계시면 됩니다.

 

 

여기까지가 MATLAB에서 패키지로 내보낸 파일을 실행시키는 방법입니다. 단순한 코드에 대해서 작성하였기 때문에 수고에 비해서 결과가 별로 없는 거 같지만 매트랩으로 복잡하게 작성된 코드를 C/C++과 연계하여 프로그램을 만들기에 이보다 좋은 방법은 없어 보입니다. 기회가 된다면 좀 더 복잡한 MATLAB 코드를 다루는 방법에 대해서도 작성해보겠습니다. 예를 들어 행렬의 초기화를 미리 해주면 앞서 얘기한 문제들을 피할 수 있다는 것과 같은 내용들입니다. 혹시 1부 및 2부의 내용을 따라 하시다가 문제가 발생하실 경우 댓글 남겨주시면 최대한 도와드리겠습니다.

 긴 글 읽어주셔서 감사합니다. 
글과 관련된 의견은 언제든지 환영입니다.
반응형

댓글