unity3D C#调用C++代码(通过DLL链接库方式)

前言】:最近自己捣鼓数据手套,想用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,如下:

#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拷贝到其中,程序也可以运行。






  • 1
    点赞
  • 11
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值