C#에서 C++ DLL 사용하기
C++ DLL return char *, C++ DLL 문자열 인자 전달
예제에서 사용된 DLL은 Unmanaged C++(관리되지 않은 C++)로 만들어졌다.
예제에서는 Static DLL 호출 방법을 사용하였다.
예제는 (Visual Studio 2012) 비주얼 스튜디오 2012에서 작성하였다.
[새 프로젝트]-[Visual C++]-[Win32 프로젝트]
솔루션이름 : JINGUDLL
응용프로그램 종류 : DLL
추가 옵션 : 빈 프로젝트
jingudll.cpp |
#include <stdio.h> #include <string.h> #include <windows.h> //LocalAlloc, LPTR #define EXPORTDLL extern "C" __declspec(dllexport) EXPORTDLL char* getMessage(); EXPORTDLL void copyMessage(char * _input, char * _output); extern "C" void printMessage(char* _input); //dll 내부의 모든 코드는 extern "C" 안에 정의 되어야 한다. extern "C" { //C#에서 불러다 쓸 수 없다. //dll 내부에서만 호출이 가능하다. char * result = "C++ Dll로부터 응답"; void printMessage(char * _input) { printf("'%s' is came from C# \n",_input); } } EXPORTDLL char* getMessage() { char * returnchar = (char*)LocalAlloc(LPTR, strlen(result)+1); strcat(returnchar, result); return returnchar; } EXPORTDLL void copyMessage(char * _input, char * _output) { printMessage(_input); strcpy(_output, _input); }
위의 소스를 빌드 후 프로젝트 폴더의 경로에 가보면 "JINGUDLL.dll" 파일이 생성되어 있다. 이 파일을 아래에 새롭게 생성한 C# 프로젝트 내의 실행 파일과 같은 경로에 파일을 복사한다.
[새프로젝트] - [Visual C#] - [콘솔 응용프로그램]
Program.cs |
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; using System.Runtime.InteropServices; namespace DLLTEST { class Program { [DllImport("JINGUDLL.dll", CallingConvention =CallingConvention.Cdecl)] private static extern IntPtr getMessage(); [DllImport("JINGUDLL.dll", CallingConvention = CallingConvention.Cdecl)] private static extern void copyMessage(StringBuilder _input, StringBuilder _output); static void Main(string[] args) { IntPtr ptr = getMessage(); string Message = Marshal.PtrToStringAnsi(ptr); Marshal.FreeHGlobal(ptr); Console.WriteLine("C++ Dll로 부터 리턴된 char* : {0}", Message); StringBuilder _input = new StringBuilder("This is value"); StringBuilder _output = new StringBuilder(); copyMessage(_input, _output); Console.WriteLine("C++ DLL 내에서 변경된 _output의 값은 {0}",_output); } } }
C, C++언어에서의 char * 에 대응 되는 C#의 자료형은 String이 아니다. StringBuilder 이다.
C, C++언어에서의 char * 리턴을 받을 때 주소값을 저장할 수 있는 IntPtr 자료형을 사용하여야 한다.
DllImport시에 CallingConvention =CallingConvention.Cdecl 을 꼭 선언해주어야 한다.
DLL에서 LocalAlloc으로 할당한 메모리는 C#에서 Marshal.FreeGlobal()로 제거해 주어야 한다.
'컴퓨터 > C#' 카테고리의 다른 글
[C#] ns(nano seconds) 나노 초 단위의 시스템 성능 측정 C# 코드 (0) | 2013.07.24 |
---|---|
[.NET] CLR(Common Language Runtime, 공통 언어 실행 환경) (0) | 2013.06.07 |
[C#] lock 블럭 (1) | 2013.06.02 |
[C#] 객체와 생성 (0) | 2013.05.28 |
[C#] get, set 함수 (0) | 2013.01.18 |