unity用的很廣泛,如今不少代碼仍是用c++寫的,須要用unity去調用c++的代碼。這裏介紹了一種unity調用c++ dll的方法,但願有所幫助。
我採用的軟件是Visual Studio 2015和 Unity 5.3.4
ios
test.cppc++
#define EXPORTBUILD #include "test.h" #include <iostream> _DLLExport int cpp_get_int_value() { return 51; } _DLLExport void cpp_get_int_ptr(int* value) { *value = 52; } _DLLExport void cpp_get_int_ref(int& value) { value = 53; } _DLLExport float cpp_get_float_value() { return 51.1f; } _DLLExport void cpp_get_float_ptr(float* value) { *value = 52.1f; } _DLLExport void cpp_get_float_ref(float& value) { value = 53.1f; } _DLLExport void cpp_get_string_value(char** str_ptr) { char* str = "hello world"; strcpy(*str_ptr, str); return; } struct cpp_struct_one { int value1; float value2; }; _DLLExport void cpp_get_struct_one_value(cpp_struct_one* stu) { stu->value1 = 10; stu->value2 = 10.1f; return; } _DLLExport void cpp_get_struct_one_value2(cpp_struct_one& stu) { stu.value1 = 11; stu.value2 = 11.1f; return; } _DLLExport void cpp_get_struct_one_value3(cpp_struct_one* stu) { stu->value1 = 12; stu->value2 = 12.1f; return; } struct cpp_struct_two { int value1[10]; float value2; }; _DLLExport void cpp_get_struct_two_value(cpp_struct_two* stu, int count) { for (int i = 0; i < count; i++) { stu->value1[i] = i; } stu->value2 = 10.1f; return; } _DLLExport void cpp_get_int_arr1(int* arr, int count) { for (int i = 0; i < count; i++) { arr[i] = i; } return; } _DLLExport void cpp_get_int_arr2(int* arr, int count) { for (int i = 0; i < count; i++) { arr[i] = i; } return; } _DLLExport void cpp_get_int_arr3(int* arr, int count) { for (int i = 0; i < count; i++) { arr[i] = i; } return; } _DLLExport void cpp_set_string_value(char* s) { std::string str = s; printf("str %s length %d", str.c_str(), str.length()); return; }
在unity在 Assets文件下文件Plugins目錄,在目錄下方放入Dll文件。要是沒有Plugins文件夾,就新建一個。
git
這裏注意,Dll文件不須要加後綴 .dllgithub
using UnityEngine; using System.Collections; using System.Runtime.InteropServices; using System.Text; using System; public class NewBehaviourScript : MonoBehaviour { [DllImport("cppDll")] private static extern int cpp_get_int_value(); [DllImport("cppDll")] private static extern void cpp_get_int_ptr(ref int value); [DllImport("cppDll")] private static extern void cpp_get_int_ref(ref int value); [DllImport("cppDll")] private static extern float cpp_get_float_value(); [DllImport("cppDll")] private static extern void cpp_get_float_ptr(ref float value); [DllImport("cppDll")] private static extern void cpp_get_float_ref(ref float value); [DllImport("cppDll")] private static extern void cpp_get_string_value(ref StringBuilder ptrStr); [StructLayout(LayoutKind.Sequential)] public struct cpp_struct_one { public int value1; public float value2; }; [DllImport("cppDll")] private static extern void cpp_get_struct_one_value(ref cpp_struct_one stu); [DllImport("cppDll")] private static extern void cpp_get_struct_one_value2(ref cpp_struct_one stu); [DllImport("cppDll")] private static extern void cpp_get_struct_one_value3(IntPtr stu); [StructLayout(LayoutKind.Sequential)] public struct cpp_struct_two { [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)] public int[] value1; public float value2; }; [DllImport("cppDll")] private static extern void cpp_get_struct_two_value(IntPtr stu, int count); [DllImport("cppDll")] private static extern void cpp_get_int_arr1(ref int arr, int count); [DllImport("cppDll")] private static extern void cpp_get_int_arr2(int[] arr, int count); [DllImport("cppDll")] private static extern void cpp_get_int_arr3(IntPtr arr, int count); [DllImport("cppDll")] private static extern void cpp_set_string_value(string s); // Use this for initialization void Start () { // 獲取int類型 int int_value = cpp_get_int_value(); Console.WriteLine("cpp_get_int_value\t " + int_value); // 獲取int類型 指針 int int_ptr = new int(); cpp_get_int_ptr(ref int_ptr); Console.WriteLine("cpp_get_int_ptr\t " + int_ptr); // 獲取int類型 引用 int int_ref = new int(); cpp_get_int_ref(ref int_ref); Console.WriteLine("cpp_get_int_ref\t " + int_ref); // 獲取float類型 float float_value = cpp_get_float_value(); Console.WriteLine("cpp_get_float_value\t " + float_value); // 獲取float類型 指針 float float_ptr = new float(); cpp_get_float_ptr(ref float_ptr); Console.WriteLine("cpp_get_float_ptr\t " + float_ptr); // 獲取float類型 引用 float float_ref = new float(); cpp_get_float_ref(ref float_ref); Console.WriteLine("cpp_get_float_ref\t " + float_ref); // 獲取結構體類型 cpp_struct_one stu = new cpp_struct_one(); cpp_get_struct_one_value(ref stu); Console.WriteLine("cpp_get_struct_one_value " + stu.value1 + " " + stu.value2); // 獲取結構體類型 方法2 cpp_struct_one stu2 = new cpp_struct_one(); cpp_get_struct_one_value2(ref stu2); Console.WriteLine("cpp_get_struct_one_value2 " + stu2.value1 + " " + stu2.value2); // 獲取結構體類型 方法3 // 使用非託管內存 int cpp_struct_one_size = Marshal.SizeOf(typeof(cpp_struct_one)); IntPtr cpp_struct_one_buffer = Marshal.AllocHGlobal(cpp_struct_one_size); cpp_get_struct_one_value3(cpp_struct_one_buffer); cpp_struct_one stu3 = (cpp_struct_one)Marshal.PtrToStructure(cpp_struct_one_buffer, typeof(cpp_struct_one)); Console.WriteLine("cpp_get_struct_one_value3 " + stu3.value1 + " " + stu3.value2); // 獲取結構體類型2(帶數組結構體) // 使用非託管內存 int cpp_struct_two_size = Marshal.SizeOf(typeof(cpp_struct_two)); IntPtr cpp_struct_two_buffer = Marshal.AllocHGlobal(cpp_struct_two_size); cpp_get_struct_two_value(cpp_struct_two_buffer, 10); cpp_struct_two stu4 = (cpp_struct_two)Marshal.PtrToStructure(cpp_struct_two_buffer, typeof(cpp_struct_two)); Console.WriteLine("cpp_get_struct_two_value " + stu4.value1[5] + " " + stu3.value2); // 獲取字符串 StringBuilder str = new StringBuilder(); cpp_get_string_value(ref str); Console.WriteLine("cpp_get_string_value " + str.ToString()); // 獲取int型數組 方法1 int[] arr1 = new int[10]; cpp_get_int_arr1(ref arr1[0], arr1.Length); Console.WriteLine("cpp_get_int_arr1 5 " + arr1[5]); // 獲取int型數組 方法2 int[] arr2 = new int[10]; cpp_get_int_arr2(arr2, arr2.Length); Console.WriteLine("cpp_get_int_arr2 5 " + arr2[5]); // 獲取int型數組 方法3 int arr3_length = 10; int arr3_size = Marshal.SizeOf(typeof(int)) * arr3_length; IntPtr arr3_buffer = Marshal.AllocHGlobal(arr3_size); cpp_get_int_arr3(arr3_buffer, arr3_length); int arr3_test_value = (int)Marshal.PtrToStructure(arr3_buffer + 5 * Marshal.SizeOf(typeof(int)), typeof(int)); Console.WriteLine("cpp_get_int_arr3 " + arr3_test_value); // 傳入字符串 string s = "hello world"; cpp_set_string_value(s); } // Update is called once per frame void Update () { } }
unity運行結果
項目地址
https://github.com/caimagic/Unity_Call_Cplusplus-s-Dll.git數組