튜토리얼
C++ Dll 에서 간단하 문자열을 포인터로 C#에 전달하는 내용이다.
2015/07/15 - [잡다한 자료(번역)/Unity3D] - Unity 과 DLL을 : C#을 (managed) 및 C++(unmanaged)
(C++ C# Dll 만드는 법)
보스전
C++ Dll 이다. 간단한 문자열을 포인터로 반환 하는 함수이며, 이떄 &로 데이터의 길이를 전달한다.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 | #ifdef FUNCDLL_EXPORT #define FUNCDLL_API __declspec(dllexport) #else #define FUNCDLL_API __declspec(dllimport) #endif extern "C" { //함수를 통해 데이터 포인터를 전달 할때 사이즈 길이를 함께 전달 하는 방법 //Call by Reference 로 전달 한다. FUNCDLL_EXPORT char* GetByte(int &size) { string str = "hello world"; size = str.size(); char* data = new char[size]; strcpy(data , str.c_str()); cout << "end function" << endl; return data; } } | cs |
strcpy 를 쓰면 머시기머시기 하며 C4996 에러가 나는데 (strcpy_s 를 쓰라고 하는 에러)
#pragma warning(disable:4996)
한 줄 딱 쓰면 에러가 제외된다.
C# 코드는 아래와 같다.
방법은 2가지 인데, 하나는 마샬링을 이용하는 방법, 다른 하나는 unsafe 블럭을 통해 직접 접근 하는 방법이다.
만약 PInvokeStackImbalance" Exception 이 발생한다면 , CallingConvention=CallingConvention.Cdecl 를 DllImport 에 붙인다.
메모리 해제도 잊지 말자.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 | using System; using System.Collections.Generic; using System.Linq; using System.Runtime.InteropServices; using System.Text; using MMF; namespace UnityTest { public partial class Form1 : Form { [DllImport("kernel32")] static extern IntPtr LocalFree(IntPtr mem); private void btnFbxOpen_Click(object sender, EventArgs e) { TCPServer.UnitySend("CreateCube", TCP.CommandType.Exit); MMF.Database.Binarywrite("10, 10, 10", 20); MMF.Database.Binaryread(); int size = 0; IntPtr data = Database.DataRe(out size); Console.WriteLine("string Length : " + size); byte[] _receiveData = new byte[size]; try { if (true) //마샬링을 이용하여 포인터를 배열로 전환 하는 방법 { Marshal.Copy(data, _receiveData, 0, _receiveData.Length); } else { unsafe //unsafe 이용하여 직접 포인터 변수에 접근 하는 방법 { Console.WriteLine("use unsafe block"); byte* ptrData = (byte*)data.ToPointer(); for (int i = 0; i < size; i++) { _receiveData[i] = (byte)ptrData[i]; } } } } finally { //메모리 해제 Console.WriteLine(true); LocalFree(data); } string result = Encoding.Default.GetString(_receiveData); Console.WriteLine("string receive from native cpp : " + result); } } } | cs |
엔딩 후 추가내용...
추가 설명 :
예제는 댓글로 필요하다는 분이 있으면 추가하겠습니다~
최근댓글