当前位置: 首页 > article >正文

Windows下Dll在Unity中使用的一般方式

Windows下Dll在Unity中使用的一般方式

Unity中虽然已经有广泛的库和插件,但是相较于C++的库生态而言,还是有一定的差距;因此本篇博文记录Windows下将C++函数打包成动态链接库在Unity中使用的一般方法。

环境

Visual Studio 2019 , Unity2022 , Windows11,OpenCV

说明

  1. Unity中有针对Windows 下DLL文件的自动加载机制,所以只要把打包好的动态链接库拷贝到 Assets/Plugins,然后在Unity脚本中进行注册便可以使用。
  2. 由于动态链接库本质上可以理解成一个插件,所以本次记录侧重 Unity和C++动态链接库函数的传参一致性问题

步骤

Visual Studio 2019

  1. 新建一个项目,在源文件中按照如下格式编写函数

​ 缩略版:

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(动态链接库)中导出,使得它可以被其他程序或库调用。

image-20250111170515174

之后进行编译,便可以得到一个dll文件。

Unity

接下来需要将动态链接库拷贝到Unity的Assets/Plugins目录:

image-20250111170709616

接下来我们新建一个脚本,在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,都是指针。

调用示例。

image-20250111171259391

PS:一个比较值得关注的点是,如果使用了第三方库,OpenCV,我们还需要把OpenCV相关的dll文件也拷贝到Assets/Plugins下,这是因为动态链接库之间也有一些依赖关系,我们需要把他们都导入进去。同时我建议如果要打包的话,因为可能跨设备运行,所以建议采用相对目录的方式,配置Visual Studio中的第三方库的依赖关系。

Refer

  • Mac下在Unity中调用C++库

  • 演练:创建和使用自己的动态链接库 (C++)


http://www.kler.cn/a/500724.html

相关文章:

  • 做一个 简单的Django 《股票自选助手》显示 用akshare 库(A股数据获取)
  • 深入解析 C++ 类型转换
  • excel VBA 基础教程
  • 鸿蒙面试 2025-01-09
  • 运维高级课作业一
  • MeCo——给预训练数据增加源信息,就能减少33%的训练量并且提升效果
  • MYSQL-创建数据库 CREATE DATABASE (十一)
  • 蠕虫病毒会给服务器造成哪些危害?
  • vue3后台系统动态路由实现
  • centos 搭建nginx+配置域名+windows访问
  • Vue 开发者的 React 实战指南:性能优化篇
  • 【Ubuntu与Linux操作系统:九、Shell编程】
  • Perl语言的编程范式
  • 简历整理YH
  • Django 社团管理系统的设计与实现
  • SpringBoot项目实战(39)--Beetl网页HTML文件中静态图片及CSS、JS文件的引用和展示
  • 如何在Go语言开发中实现高性能的分布式日志收集
  • 【微服务】面试 2、服务雪崩
  • 【网络】:网络编程套接字
  • 《机器学习》集成学习之随机森林
  • 双因素身份验证技术在NPI区域邮件安全管控上的解决思路
  • Java Web开发基础:HTML的深度解析与应用
  • 基于SSM实现的垃圾分类平台系统功能实现二
  • CSS3 弹性盒子