Unity——在C#中调用C++动态链接库(DLL)

news2024/11/16 12:30:50

一、创建C++动态链接库(DLL)

1、新建C++空项目

打开VS,新建一个C++空项目,自命名项目名称与位置。

2、配置项目属性为动态链接库

右键项目,点击属性,打开项目属性页,将常规中的配置类型改为动态库(.dll)。

 3、添加.h头文件

右键头文件,点击添加—>新建项,选择头文件.h,命名为DllForUnity.h,点击添加。

代码如下: 

#pragma once
#include<math.h>
#include<string.h>
#include<iostream>
#define _DllExport _declspec(dllexport) //使用宏定义缩写下
 
 
extern "C"
{
   float _DllExport GetDistance(float x1, float y1, float x2, float y2);
}

4、添加.cpp文件

右键源文件,点击添加—>新建项,选择C++文件.cpp,命名为DllForUnity.h,点击添加。

代码如下: 

#include <DllForUnity.h>

float GetDistance(float x1, float y1, float x2, float y2)
{
    return sqrt((x1 - x2) * (x1 - x2) + (y1 - y2) * (y1 - y2));
}

5、设置编译为C++代码

右击项目,点击属性,对C/C++下面的高级中的编译为选择“编译为C++代码(/TP)”。

6、生成解决方案

点击生成->生成解决方案,生成之后,会显示出生成成功。

7、确定生成.dll文件

在项目路径下x64文件夹的Debug中就可以看到生成的.dll文件

二、将Dll库在Unity工程中调用

1、创建Unity工程

打开Unity创建新项目,添加两个Cube,分别命名为Cube1、Cube2,添加一个空物体命名为Main。

2、将Dll文件放入Unity项目中

在项目下的Assets文件夹下新建一个文件夹命名为Plugins,将之前生成的动态链接库放到Plugins文件夹下

3、新建脚本调用C++代码

新建Main.cs脚本,并把脚本挂载在Main的空物体下。

代码如下:

using System.Collections;
using System.Collections.Generic;
using System.Runtime.InteropServices;
using UnityEngine;

public class Main : MonoBehaviour
{
    private GameObject cube1;
    private GameObject cube2;
    // Use this for initialization
    void Start()
    {
        cube1 = GameObject.Find("Cube1");
        cube2 = GameObject.Find("Cube2");
        PrintDistanceViaUnity();
    }

    [DllImport("CppAndCS.dll")]
    public static extern float GetDistance(float x1, float y1, float x2, float y2);

    void PrintDistanceViaUnity()
    {
        var pos1 = cube1.transform.position;
        var pos2 = cube2.transform.position;
        Debug.Log("Distance of Two Cube");
        Debug.Log("Distance:" + GetDistance(pos1.x, pos1.y, pos2.x, pos2.y));
    }
}

4、运行结果

控制台输出两个方块的距离,说明成功调用C++的GetDistance方法。

 注:如果Unity已经在运行并且Dll已经存在,那么新的Dll写入生成会失败,此时需要关掉Unity再重新生成。

可能遇到的问题

问题1

问题描述:#include <DllForUnity.h>报错:无法打开源文件。

解决方法:依次点击“项目——配置属性——C/C++——常规”,在“附加包含目录”中加入.h文件所在的文件夹路径。

问题2

问题描述:unity控制台报错: 

 Assets\Main.cs  error CS0246: The type or namespace name 'DllImportAttribute' could not be found (are you missing a using directive or an assembly reference?)

Assets\Main.cs   error CS0246: The type or namespace name 'DllImport' could not be found (are you missing a using directive or an assembly reference?)

 解决方法:

1:一定要 using System.Runtime.InteropServices;

2: [DllImport(“XXXX”)] 需要放在类里面使用

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/594711.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

无需租云服务器,Linux本地搭建web服务,并内网穿透发布公网访问(1)

文章目录 前言1. 本地搭建web站点2. 测试局域网访问3. 公开本地web网站3.1 安装cpolar内网穿透3.2 创建http隧道&#xff0c;指向本地80端口3.3 配置后台服务 4. 配置固定二级子域名5. 测试使用固定二级子域名访问本地web站点 转载自cpolar文章&#xff1a;Linux CentOS本地搭建…

HTB soccer

title: HTB_soccer description: HTB靶机 难度&#xff1a;easy date: 2023-05-31 categories: [渗透,靶机] HTB soccer 信息收集 ┌──(kali㉿kali)-[~] └─$ sudo nmap --min-rate 10000 -p- 10.10.11.194 [sudo] kali 的密码&#xff1a; Starting Nmap 7.93 ( https:/…

路径规划算法:基于水循环优化的路径规划算法- 附代码

路径规划算法&#xff1a;基于水循环优化的路径规划算法- 附代码 文章目录 路径规划算法&#xff1a;基于水循环优化的路径规划算法- 附代码1.算法原理1.1 环境设定1.2 约束条件1.3 适应度函数 2.算法结果3.MATLAB代码4.参考文献 摘要&#xff1a;本文主要介绍利用智能优化算法…

【数据分享】1929-2022年全球站点的逐年最高气温(Shp\Excel\12000个站点)

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、湿度等指标&#xff0c;其中又以气温指标最为常用&#xff01;说到气温数据&#xff0c;最详细的气温数据是具体到气象监测站点的气温数据&#xff01; 之前我们分享过1929-2022年全球气象站…

工业智能终端配合MES系统真的可以提高生产效率吗?

工业智能终端可以实现数据分析和预测&#xff0c;通过对生产数据的分析和预测&#xff0c;可以更好地把握生产趋势和变化&#xff0c;及时调整生产计划和资源配置&#xff0c;提高生产效率和降低成本。 工业显示交互终端&#xff1a;解决MES系统软硬结合的难题&#xff0c;集显…

交叉编译成LoongArch(Makefile,CMake,AutoTool,Qt等方式)

在嵌入板卡中由于资源有限常常使用像busybox这样的轻量文件系统。由于这类轻量文件系统没有编译系统在里面&#xff0c;所以如果需要软件在板卡上运行&#xff0c;那么交叉编译是必不可少的。 如果对交叉编译(cross compile)这个概念不太清楚的话&#xff0c;可以参考以下的一…

加盐算法:手撕+Spring Security、提高密码安全性的必杀技

目录 一、概念和理解 &#xff08;一&#xff09;MD5加密 &#xff08;二&#xff09;加密解密过程 &#xff08;三&#xff09;加盐 1.什么是盐值&#xff1f; 2.如何加盐? 二、手写加盐算法 &#xff08;一&#xff09;密码工具类 &#xff08;二&#xff09;项目改动 注册 …

Spring Boot如何实现自定义Spring Boot启动器

Spring Boot如何实现自定义Spring Boot启动器 在Spring Boot中&#xff0c;启动器&#xff08;Starter&#xff09;是一组依赖项的集合&#xff0c;它们一起提供了某个特定的功能。使用Spring Boot启动器可以让我们更加方便地集成第三方库和框架&#xff0c;并且可以避免版本冲…

2023年京东618预售数据重磅出炉!(大家电篇:预售额550亿)

2023年5月23日至5月31日&#xff0c;京东618预售期正式落幕。今年的预售&#xff0c;不少行业及品牌首战告捷&#xff0c;拿下了不错的成绩。 数据统计时间&#xff1a;5月23日至5月30日 平台&#xff1a;京东 今晚&#xff0c;鲸参谋率先来盘点一下大家电行业在23日至30日预售…

知名大厂的UI组件库有哪些?

以下是 5 款优秀的 UI 设计组件库的推荐&#xff0c;这些组件库都可以免费获取&#xff0c;帮助你解答疑惑&#xff0c;提供设计参考&#xff0c;并提高工作效率 1、MUI&#xff08;Material-UI&#xff09; 包含 60 类别的 UI 设计组件&#xff0c;可在即时设计资源广场一…

开源!AREX接口自动化回归测试的全过程

AREX是一款开源的基于真实请求与数据的自动化回归测试平台&#xff08;项目地址&#xff1a;https://github.com/arextest&#xff09;&#xff0c;利用JavaAgent技术与比对技术&#xff0c;通过流量录制回放能力实现快速有效的回归测试。同时提供了接口测试、接口比对测试等丰…

Sentinel 介绍及整合OPenFeign及GateWay

Sentinel 介绍 随着微服务的流行&#xff0c;服务和服务之间的稳定性变得越来越重要。 Sentinel 以流量为切入点&#xff0c;从流量控制、熔断降级、系统负载保护等多个维度保护服务的稳定性。 Sentinel 具有以下特征: 丰富的应用场景&#xff1a; Sentinel 承接了阿里巴巴近…

IDEA 插件上新! 生成接口文档就是这么快!

当有接口对接需求的时候&#xff0c;开发终于不用再担心 API 文档难写了&#xff0c;也不用再一个个接口文档重新写&#xff01;安装这个 IDEA 插件&#xff0c;可以一步将文档导入到 Postcat。 这款插件操作简单&#xff0c;容易上手&#xff0c;能够让开发者省去API文档编写的…

STM32G0x0系列-软件定时器解决HAL_Delay问题

目录 HAL_Delay函数源码 软件定时器 创建工程试验 1.将对应文件移动到项目位置 2.添加现有文件放到工程中 3.重定向printf 3.验证自己的软件定时器 4.查看现象 HAL_Delay函数使用了中断机制来实现延时功能&#xff0c;当在中断函数中调用HAL_Delay函数需要考虑中断优先…

《操作系统》by李治军 | 实验5.pre - copy_process 代码详解

目录 【前言】 代码分析 1. 申请子进程 PCB 空间 2. 找到子进程的内核栈 3. 父子进程共用同一内存、堆栈和数据代码块 4. 相关寄存器入栈 5. switch_to 返回位置 6. 响应 switch_to 的弹栈工作 7. 更新子进程 PCB 8. 子进程切换流程 【前言】 在李治军老师的《操作系…

MyBatis——缓存

是一种临时存储少量数据至内存或者是磁盘的一种技术.减少数据的加载次数,可以降低工作量,提高程序响应速度 缓存的重要性是不言而喻的。mybatis的缓存将相同查询条件的SQL语句执行一遍后所得到的结果存在内存或者某种缓存介质当中&#xff0c;当下次遇到一模一样的查询SQL时候…

Yolov8涨点神器:ODConv+ConvNeXt提升小目标检测能力

1.涨点神器结合,助力YOLO 1.1 ICLR 2022涨点神器——即插即用的动态卷积ODConv 论文:Omni-Dimensional Dynamic Convolution 论文地址:Omni-Dimensional Dynamic Convolution | OpenReview ODConv通过并行策略引入一种多维注意力机制以对卷积核空间的四个维度学习更灵活的…

项目所需的Python版本+国内源+虚拟环境+用Conda创建环境

文章目录 &#xff08;一&#xff09;Python&#xff08;1.1&#xff09;国内源&#xff08;1.2&#xff09;设置源&#xff08;全局&#xff09;&#xff08;1.3&#xff09;使用源&#xff08;单次&#xff09; &#xff08;二&#xff09;Python环境&#xff08;2.1&#xf…

【数据结构与算法】力扣:栈和队列(一)

1 请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作&#xff08;push、pop、peek、empty&#xff09;&#xff1a; 实现 MyQueue 类&#xff1a; void push(int x) 将元素 x 推到队列的末尾 int pop() 从队列的开头移除并返回元素 int peek() 返回队列开…