Windows下Dll在Unity中使用的一般方式
Windows下Dll在Unity中使用的一般方式
Unity中虽然已经有广泛的库和插件,但是相较于C++的库生态而言,还是有一定的差距;因此本篇博文记录Windows下将C++函数打包成动态链接库在Unity中使用的一般方法。
环境
Visual Studio 2019 , Unity2022 , Windows11,OpenCV
说明
- Unity中有针对Windows 下DLL文件的自动加载机制,所以只要把打包好的动态链接库拷贝到
Assets/Plugins,然后在Unity脚本中进行注册便可以使用。 - 由于动态链接库本质上可以理解成一个插件,所以本次记录侧重 Unity和C++动态链接库函数的传参一致性问题。
步骤
Visual Studio 2019
- 新建一个项目,在源文件中按照如下格式编写函数
缩略版:
extern "C" {
// 变量
static bool isModelInitialized = false;
__declspec(dllexport) int add( int width, int height) {
return width + height;
}
}
Demo:
#include "opencv2/highgui.hpp"
#include "opencv2/core.hpp"
#include "opencv2/imgproc.hpp"
//#include"opencv2/xfeatures2d.hpp"
#include "SFace.h"
#include "opencv2/dnn.hpp"
#include "opencv2/calib3d.hpp"
#include "opencv2/video.hpp"
#include "face_detector.hpp"
#include <iostream>
using namespace cv;
using namespace declass;
extern "C" {
//
static bool isModelInitialized = false;
static YOLOv8_face* fdModel = nullptr;
static SFace* face_recognizer = nullptr;
static Mat targetFeature;
__declspec(dllexport) bool reGetStartFaceBox(unsigned char* pixelData, int width, int height, int* box) {
return false;
}
__declspec(dllexport) bool getStartFaceFeature(unsigned char* pixelData, int width, int height) {
return true;
}
// 释放资源的函数
__declspec(dllexport) void Cleanup() {
{
delete fdModel;
delete face_recognizer;
fdModel = nullptr;
face_recognizer = nullptr;
isModelInitialized = false;
}
extern "C" 是一种 C++ 中的语言链接约定,用于指示编译器以 C 的方式处理函数的名称修饰(name mangling)规则。
__declspec(dllexport) 是 Microsoft 编译器特有的一个声明符,用于声明某个函数、变量或类在 DLL(动态链接库)中导出,使得它可以被其他程序或库调用。

之后进行编译,便可以得到一个dll文件。
Unity
接下来需要将动态链接库拷贝到Unity的Assets/Plugins目录:

接下来我们新建一个脚本,在Unity中注册我们编写好的函数
public class FaceRecongnize
{
// faceRecong是dll文件名字,函数名和上面的demo是一致的。
[DllImport("faceRecong", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern bool reGetStartFaceBox(IntPtr pixelData, int width, int height, int[] box);
[DllImport("faceRecong", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern bool getStartFaceFeature(IntPtr pixelData, int width, int height);
[DllImport("faceRecong", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern void Cleanup();
}
至于参数,比如我想把一个纹理,或者一个数组传入到动态链接库中进行赋值,一般是用指针进行传送,比如上面的纹理数据和box,都是指针。
调用示例。

PS:一个比较值得关注的点是,如果使用了第三方库,OpenCV,我们还需要把OpenCV相关的dll文件也拷贝到Assets/Plugins下,这是因为动态链接库之间也有一些依赖关系,我们需要把他们都导入进去。同时我建议如果要打包的话,因为可能跨设备运行,所以建议采用相对目录的方式,配置Visual Studio中的第三方库的依赖关系。
Refer
Windows下Dll在Unity中使用的一般方式的更多相关文章
- Python调用windows下DLL详解
Python调用windows下DLL详解 - ctypes库的使用 2014年09月05日 16:05:44 阅读数:6942 在python中某些时候需要C做效率上的补充,在实际应用中,需要做部分 ...
- 【Windows下DLL查找顺序 】
一.写作初衷 在Windows下单个DLL可能存在多个不同的版本,若不特别指定DLL的绝对路径或使用其他手段指定,在应用程序加载DLL时可能会查找到错误的版本,进而引出各种莫名其妙的问题.本文主要考虑 ...
- 在windows下的QT编程中的_TCHAR与QString之间的转换
由于在windows下的QT编程中,如果涉及到使用微软的API,那么不可避免使用_TCHAR这些类型,因此在网上查了一下,其中一个老外的论坛有人给出了这个转换,因此在这里做一下笔记 : )#ifdef ...
- windows下命令行模式中cd命令无效的原因
当我们执行cmd 想切换当前工作目录时,会发现windows下命令行模式中cd命令没有生效,到底是什么原因呢? 例如: 当我们想切换到 D:\MySql\mysql-5.7.19-winx64\bin ...
- .pages怎么在windows上打开?Windows下打开在Mac中编辑的.pages文件方法
.pages怎么在windows上打开?Windows下打开在Mac中编辑的.pages文件方法 1.最简单的方法是修改后缀名为.zip然后解压,解压后就可以看到一张图片,这个就是文档内容了. 2.更 ...
- Redis在windows下安装和PHP中使用
1.redis简介redis是一个key-value存储系统.和Memcached类似,它支持存储的value类型相对更多,包括string(字符串).list(链表).set(集合).zset(so ...
- Windows下DLL查找顺序
目录 第1章说明 2 1.1 查找顺序 2 1.1.1 检查DllCharacteristics字段 3 1.1.2 读取manifset资源 3 1.1.3 读取manifs ...
- Python调用windows下DLL详解 - ctypes库的使用
在python中某些时候需要C做效率上的补充,在实际应用中,需要做部分数据的交互.使用python中的ctypes模块可以很方便的调用windows的dll(也包括linux下的so等文件),下面将详 ...
- windows下在文件夹中快速启动cmd
在windows下,有时候由于特定需要,我们经常需要将cmd cd到某文件下进行命令行操作,其实,这里有一个小技巧: 在一个文件下,按住shift键,然后点击鼠标右键,你就会发现菜单栏中多出一个“在 ...
- 学习笔记——Windows下cocos2d-x,eclipse中自编译
cocos2d-x创建的安卓项目导入eclipse后. 在项目属性中配置Builders. 在eclipse编译还需要配置相应的变量,即后面提到的cygwin编译中要添加的变量. D:/cygdriv ...
随机推荐
- kubernetes系列(六) - 资源清单
目录 1. kubernetes中的资源 1.1 定义 1.2 资源类型 1.2.1 工作负载型资源对象(workload) 1.2.2 服务发现及均衡资源对象 1.2.3 配置与存储资源对象 1.2 ...
- 外部H5唤起常用小程序链接规则整理
概述 我目前工作是全职做小程序开发,所负责的小程序需要发布抖音+快手+微信+支付宝四端,年底了,公司准备做一波营销活动,营销活动更好传播的话首选H5活动营销页,这就需要考虑怎么把用户从H5页面引入到我 ...
- java技术架构图
架构图有哪几种 业务架构:需求初期业务的结果和过程描述一般比较模糊,可能来自于某个老板.运营或用户的反馈.客户说海尔洗衣机洗土豆会堵,海尔立马设计专门的土豆洗衣机 业务方向往往是定方向和结果的叫战略, ...
- MySQL---索引-性能-配置参数优化
一般来说,要保证数据库的效率,要做好以下四个方面的工作:数 据库设计.sql语句优化.数据库参数配置.恰当的硬件资源和操作系统,这个顺序也表现了这四个工作对性能影响的大小.下面我们逐个阐明: 1.设计 ...
- Flume架构与源码分析-整体架构
最近在学习Flume源码,所以想写一份Flume源码学习的笔记供需要的朋友一起学习参考. 1.Flume介绍 Flume是cloudera公司开源的一款分布式.可靠地进行大量日志数据采集.聚合和并转移 ...
- 为什么使用ROS的remap标签不起作用?
1. remap的作用 remap可以让ROS节点订阅发布的topic名字更换为另外一个名字.例如 <remap from="/old_topic" to="/ne ...
- RELIC库学习
<RELIC库学习> 文章介绍:密码学与区块链技术实验室向开源项目RELIC贡献国密算法代码 了解 RELIC是由Diego F. Aranha开发的高效.灵活的开源密码原语工具箱,包含多 ...
- [Java] Solon 框架的三大核心组件之一插件扩展体系
1.Solon 的三大核心组件 核心组件 说明 Plugin 插件扩展机制 提供"编码风格"的扩展体系 Ioc/Aop 应用容器 提供基于注入依赖的自动装配体系 Context+H ...
- ORACLE事物隔离级别和脏读、幻读、不可重复读区别
一.事务和隔离级别 事务的概念:事务是把对数据库的一系列操作都看做一个整体,要么全部成功,要么全部失败,利用事务我们可以保证数据库的完整性,事务具有原子性. 隔离级别:隔离级别定义了事务与事务之间的隔 ...
- SOUI4.0发布
4.0在3.x基础上将核心对象全部COM接口化,支持C语言调用SOUI. GIT仓库: gitee: https://gitee.com/setoutsoft/soui4 github: https: ...