Unity通过Swig工具调用C++代码学习

昨天学习了一下 Unity 调用 C++ 代码,实现了最基本的从编辑器中导出 DLL 并在Unity 的C# 中通过 DLLImport 来调用C++方法的功能,但总感觉这个流程过于繁琐,DeepSeek 后得知了 Swig 这个工具,能生成C#接口,方便调用C++逻辑。网上找的教程实践下来有点问题,好在目前解决了,我在这里记录一下整体的流程。

学习自
Unity/C++混合编程全攻略——Swig篇
C#利用SWIG调用C++的DLL

具体的 Swig 使用方法还需读者自行学习,本文仅用来记录环境安装和测试过程
本人的编辑器版本是 VS2022


环境准备阶段

Swig 下载地址
我选择的红框内的下载地址,因为里面包含可执行exe
在这里插入图片描述
配置环境变量中的Path
在这里插入图片描述
在命令行工具中输入有如下反馈则说明安装ok了

基础项目准备

新建工程 TestCallCpp

在这里插入图片描述
我们设置工程的属性:
在这里插入图片描述
在这里插入图片描述

C++代码编写

添加类 Misc,我们在其中放入工具方法,方便后续在 Unity 中调用

// 文件 Misc.h
#pragma once

extern "C"
{
	float GetDistance(float x1, float y1, float x2, float y2);
}
// 文件 Misc.cpp
#include "Misc.h"
#include <cmath>

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

为什么通常推荐使用 extern "C"
C++的名称修饰(Name Mangling):C++编译器会对函数名进行修饰(根据函数名、参数类型、命名空间等生成唯一符号),这会导致你在Unity/C#中通过[DllImport]查找函数时失败,因为函数名可能被修饰成类似?MyFunction@@YAXH@Z的形式。
extern "C"的作用:它会禁用C++的名称修饰,确保函数以C风格的简单名称(如MyFunction)导出,方便其他语言(如C#)通过名称直接调用。
右键工程并生成之后,我们在这个路径下找到了生成的DLL(这个DLL不要用,这里是只验证项目是可运行的
在这里插入图片描述
好的,我们工程准备完成了,下一步使用 swig 生成 C# 和对应的dll文件

生成流程

我们在工程下创建一个 swig 的筛选目录,并在其下创建一个 wrapper.i 的自定义文件
在这里插入图片描述
我们右键 wrapper.i 点击属性,修改项类型为“自定义生成工具”,并修改如下内容
在这里插入图片描述

  • 修改命令行
echo on
swig.exe -c++ -csharp -outdir "$(SolutionDir)\swig_wrap_result" "%(FullPath)"
echo off

命令行为执行 swig 并输出C#代码到项目的 swig_wrap_result 目录下,我们需要在工程根目录下创建 swig_wrap_result 目录
在这里插入图片描述

  • 修改输出
%(Filename)_wrap.cxx

输出一个服务于生成dll的中间件(个人理解)

  • 勾选将输出视为内容为 True
    在这里插入图片描述
    接下来我们编辑 wrapper.i 文件
%module TestCallCpp
%{
#include "Misc.h"
%}
%include "Misc.h"

右键 wrapper.i 点击后,我们发现在工程里生成了一个 wrapper_wrap.cxx 的文件
在这里插入图片描述
此时我们在 swig 下添加现有项 wrapper_wrap.cxx 并确保其 配置属性->C/C++->预编译头 为“不使用预编译头”
在这里插入图片描述
在这里插入图片描述

最后,我们右键工程,并点击生成后,等待小段时间后,我们会发现生成了如下 C# 文件
在这里插入图片描述

和如下目录中的DLL文件
在这里插入图片描述


C#(Unity)使用

我们新建一个Unity工程,在 Assets 下创建 Plugins 目录,并将 DLL 丢进来,然后复制 上述步骤中生成的 C# 脚本到工程下
在这里插入图片描述
Unity 的工程目录如下
在这里插入图片描述

在 Unity 中,我们创建一个 Test 脚本并挂载在一个空 Object 上

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class Test : MonoBehaviour
{
    void Start()
    {
        Vector2 one = Vector2.zero;
        Vector2 two = new Vector2(10, 0);
        float distance = TestCallCpp.GetDistance(one.x, one.y, two.x, two.y);
        Debug.Log(distance);
    }
}

点击执行后:
在这里插入图片描述
成功

编译导出脚本

TODO

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值