unity3D C#调用C++代码(通过DLL链接库方式)
2018-01-26 13:48
1436 查看
【前言】:最近自己捣鼓数据手套,想用unity3D集成数据手套CyberGlove,开发一个数据手套可以控制的虚拟手交互场景。还没开始就遇到一个麻烦的问题,unity3D支持C#脚本,而数据手套CyberGlove只提供了静态链接库.lib和头文件.h作为开发的SDK。于是乎如何在unity3D中获取数据手套的各指关节角度成为一个麻烦事,经过多方查询资料,初步形成了以下方案。
【方案】:分析unity3D中需要用到数据手套CyberGlove的那些API,将其提取出来进行封装,即在VS上建立DLL工程,然后定义新的函数,这些函数调用数据手套CyberGlove的API,接着将工程编译生成DLL。然后在unity3D通过调用该DLL中的函数,间接调用数据手套的原始API。借鉴网上C#调用C++ DLL库的方法,整个实现过程记录如下。
【步骤】
(1)提取unity3D需要调用数据手套API,如下:
(3)unity3D中调用DLL函数,a)将上述DLL文件拷贝到unity3D工程的assert/Plugins目录下,在C#文件最上方添加命名空间,using System.Runtime.InteropServices; 然后在需要调用DLL中的函数的地方(C#函数外)添加函数声明,格式如下:
【方案】:分析unity3D中需要用到数据手套CyberGlove的那些API,将其提取出来进行封装,即在VS上建立DLL工程,然后定义新的函数,这些函数调用数据手套CyberGlove的API,接着将工程编译生成DLL。然后在unity3D通过调用该DLL中的函数,间接调用数据手套的原始API。借鉴网上C#调用C++ DLL库的方法,整个实现过程记录如下。
【步骤】
(1)提取unity3D需要调用数据手套API,如下:
#include <vhandtk/vhtBase.h> 1、获得手套的连接 vhtIOConn *gloveConn = vhtIOConn::getDefault(vhtIOConn::glove); 2、创建手套 vhtCyberGlove *glove = new vhtCyberGlove(gloveConn); 3、手套刷新 glove->update(); 4、获取角度 double distalAngle = glove->getAngle(GHM::index, GHM::distal); for( int finger = 0; finger < GHM::nbrFingers; finger++ ) { for( int joint = 0; joint < GHM::nbrJoints; joint++ ) { glove->getData( (GHM::Fingers)finger,(GHM::Joints)joint) } } //设置震动幅度 double vibrations[] = {.5, .5, .5, .5, .5, .5}; myTouchGlove->setVibrationAmplitude( vibrations );(2)利用VS制作DLL库,基本代码模板如下:
头文件 XXX.h: #if defined (EXPORTBUILD) # define _DLLExport __declspec (dllexport) # else # define _DLLExport __declspec (dllimport) #endif extern "C" int _DLLExport 函数名(参数列表); 源文件 XXX.cpp #define EXPORTBUILD #include "XXX.h" int _DLLExport 函数名(参数列表) { 实现 }需要注意的是,编译之前还需要进行一项设置,项目属性->配置属性->常规->项目默认值->公共语言运行时支持,选择“公共语言运行时支持(/clr)”,然后编译生成DLL文件。
(3)unity3D中调用DLL函数,a)将上述DLL文件拷贝到unity3D工程的assert/Plugins目录下,在C#文件最上方添加命名空间,using System.Runtime.InteropServices; 然后在需要调用DLL中的函数的地方(C#函数外)添加函数声明,格式如下:
[DllImport ("DLL文件.dll", CallingConvention=CallingConvention.Cdecl), EntryPoint="新函数名")] [private] static extern int 函数名(参数列表);其中,CallingConvention为入口点调用约定,EntryPoint为入口点名称。其余还有很多参数可以根据需要设置,
[AttributeUsage(AttributeTargets.Method)] public class DllImportAttribute: System.Attribute { public DllImportAttribute(string dllName) {…} //定位参数为dllName public CallingConvention CallingConvention; //入口点调用约定 public CharSet CharSet; //入口点采用的字符接 public string EntryPoint; //入口点名称 public bool ExactSpelling; //是否必须与指示的入口点拼写完全一致,默认false public bool PreserveSig; //方法的签名是被保留还是被转换 public bool SetLastError; //FindLastError方法的返回值保存在这里 public string Value { get {…} } }接下来就可以直接调用DLL中的函数了。最后需要补充一点,上述调用方式属于非托管调用。此外,如果unity3D发布成了exe,在其所在目录中,建立Plugins文件夹,并将DLL拷贝到其中,程序也可以运行。
相关文章推荐
- C++通过DLL调用C#代码
- C++通过DLL调用C#代码
- C++通过DLL调用C#代码
- C++ 通过代码托管的方式调用c#的httpAgilityPack库
- C++通过DLL调用C#代码
- C++通过DLL调用C#代码
- C++通过DLL调用C#代码
- C++通过DLL调用C#代码
- C# 调用C++的dll,通过DllImport方式。 from http://www.cnblogs.com/xiaokang088/archive/2011/04/08/2009673.html
- C++通过DLL调用C#代码
- C++通过DLL调用C#代码
- C++ 通过DLL调用C#代码
- C#调用C(C++)dll示例教程,包含dll找不到函数入口的解决办法,包含C#dll调用方式不对出错的解决办法
- 通过CLR API实现C++调用C#代码交互
- 非托管C++代码调用C#编写的dll方法
- C#通过COM组件调用C++的代码
- C# 调用Dll中非托管C++代码时,函数参数的类型对照
- PB8调用使用C++与C#分别编写生成解压缩带有密码的zip压缩文件的动态链接库dll(部分内容转自互联网)
- Unity3D中使用C#调用C++编写的DLL
- C#调用C++的DLL搜集整理的所有数据类型转换方式