摘要

unity用的很普遍,现在很多代码还是用c++写的,需要用unity去调用c++的代码。这里介绍了一种unity调用c++ dll的方法,希望有所帮助。

我采用的软件是Visual Studio 2015和 Unity 5.3.4


1. 建立VS DLL 工程




2. cpp代码编辑

test.cpp

#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;
}

3. 构建Dll 文件

4. unity 工程创建

在unity在 Assets文件下文件Plugins目录,在目录下方放入Dll文件。要是没有Plugins文件夹,就新建一个。

5. unity 代码编辑

这里注意,Dll文件不需要加后缀 .dll

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

unity调用c++ dll方法介绍的更多相关文章

  1. UNITY调用安桌方法出现 JNI: Init'd AndroidJavaClass with null ptr!

    UNITY调用安桌方法出现 JNI: Init'd AndroidJavaClass with null ptr! 原因是····· 得运行在一个真正的Android设备上! 得运行在一个真正的And ...

  2. c# 调用c++DLL方法及注意事项

    引用命名空间 using System.Runtime.InteropServices 调用方法: 一.静态加载 用DllImprot方式来加载c++DLL.如下格式: //对应c++方法 //voi ...

  3. C# 调用 C++ DLL方法

    在C# 中,可以通过 DllImport 调用C++ 的非托管DLL程序. VS2010中C#调用C++的DLL示例: 一.新建C++ DLL程序 1.新建 C++ Win32项目,类型为DLL. 生 ...

  4. 制作和unity调用动态链接库dll文件

    首先用vc建立一个dll工程 然后在里面建立一个testunity.h文件.内容如下 1 extern "C" int _declspec(dllexport)testunity( ...

  5. unity调用摄像头的方法

    http://blog.csdn.net/cocoa_china/article/details/10527995 using UnityEngine; using System.Collection ...

  6. ocx控件 编译成C#调用的dll 方法 转

      打开VS命令提示行 1.注册ActiveX控件(带上 VCbox.ocx的路径) regsvr32  VCbox.ocx 2.编译OCX文件 aximp VCbox.ocx 生成两个dll文件,项 ...

  7. unity调用C++ dll文件

    首先建立Plugins文件夹,把dll文件放在里面 一一对应,我踩的坑是文件名加了后缀.dll,虽然不知道网上为什么都加了我这加了就报找不到dll文件错误,反正解决啦

  8. Unity 调用 Android Native 方法(一) 获得Android系统音量

    学习雷锋,好榜样,接下来的这一系类教程里,将通过unity来实现Android端的一些常用功能, 不需要在 Asset/Plugins/Android 目录下引用jar包或者aar包,这是重点. us ...

  9. Android-WebView与本地HTML (Java调用--->HTML的方法)

    上一篇博客 Android-WebView与本地HTML (HTML调用-->Java的方法) 介绍了 JavaScript 调用--> Java中的方法,而此篇博客是介绍 Java 调用 ...

随机推荐

  1. 日本語の文法⇒ day1 限る型…意向形の紹介

    1)限る型 ① 不仅仅 名+に限らず この漫画は子供に限らず.大人にも人気が高い. 最近は女性に限らず.男もダイエットに励む人が多い. ②仅仅....名+限って 当店は.本日に限って半額をセールを実施 ...

  2. 从SVN到Git最强指南

    对于软件开发人员来说,版本控制系统他们再熟悉不过了,所谓版本控制系统就是软件项目开发过程中用于储存开发人员所写代码所有修订版本的软件.它的主要目的是实现开发团队并行开发.提高开发效率,对软件开发进程中 ...

  3. iOS开发中如何创建多个target

    在开发iOS应用程序的过程中,经常需要根据不同的需求,切换到不同的项目配置,或者打不同的包(测试环境.开发环境.生产环境等等),如果每次都是手动配置,一则比较麻烦,二则容易配置错,那么有没有更好的方案 ...

  4. CentOS 7 服务器配置--安装MongoDB

    #下载MongoDB源文件: wget https://fastdl.mongodb.org/linux/mongodb-linux-x86_64-rhel70-3.4.7-tgz 注意:wget此处 ...

  5. 漫谈ELK在大数据运维中的应用

    漫谈ELK在大数据运维中的应用 圈子里关于大数据.云计算相关文章和讨论是越来越多,愈演愈烈.行业内企业也争前恐后,群雄逐鹿.而在大数据时代的运维挑站问题也就日渐突出,任重而道远了.众所周知,大数据平台 ...

  6. 陈年佳酿之 - Winform ListView 控件 double click 事件中获取选中的row与column

    背景 最近收到了一个关于以前项目的维护请求,那时的楼主还是刚刚工作的小青年~~~ 项目之前使用的是.net/winform.今天重新打开代码,看着之前在FrameWork2.0下面的代码, 满满的回忆 ...

  7. github+hexo搭建自己的博客网站(一)基础入门

    github提供的page,hexo提供的静态博客文档,这样可以搭建一个自己的一个博客网站. 使用github pages服务搭建博客的好处有: 全是静态文件,访问速度快: 免费方便,不用花一分钱就可 ...

  8. sp1是什么意思

    sp1是什么意思... ----------------------------- ------------------------------ 一.补丁包 SP = service pack ,补丁 ...

  9. WeQuant交易策略—BOLL

    BOLL(布林线指标)策略 简介 BOLL(布林线)指标是技术分析的常用工具之一,由美国股市分析家约翰•布林根据统计学中的标准差原理设计出来的一种非常简单实用的技术分析指标.一般而言,价格的运动总是围 ...

  10. 奇货商城重构——webpack自动化工程

    近几年,前端各种框架工具层出不穷,从两三年前还是一个jQuery搞定全站,到之后requirejs/seajs,node,gulp/webpack,Angular/React/Vue,RN/weex的 ...