如何在 Unity 3D 中包含 SWIG 包装的C++

How can I include SWIG-wrapped C++ in Unity 3D?

本文关键字:SWIG 包装 C++ 包含 Unity 3D      更新时间:2023-10-16

我的目标是获得一个使用 SWIG 包装的玩具C++库,并且可以在 Unity 中访问 C#/Mono 脚本。(换句话说,让库功能在游戏的 Windows 版本中工作。我下:)会解决安卓问题

我一直在关注构建C#模块(SWIG教程(,Unity和DLL(Eric Eastwood(和Visual Studio项目的SWiG入门(技术配方(的组合。我在Visual Studio 2013中生成了两个DLL,并将它们添加到Unity项目中。但是在运行时访问玩具方法会失败。


遵循的步骤(包括我收到的错误的常见修复(:

创建C++项目/自定义版本

  • 在 Visual Studio 中创建 C++ Win32 控制台应用程序项目
    • (因为 Windows 上的 MonoDevelop 无法C++编译(
  • 向项目添加示例代码
  • 创建 example.i(SWIG 的接口文件(
  • 为接口文件创建自定义构建工具
  • 执行自定义生成工具(为 C++ 和 C# 生成包装器代码(
  • 将C++包装器代码添加到项目中(稍后将用于生成C++ DLL(

创建 C# 项目

  • 在 Visual Studio 中创建 C# 类库项目
  • 更改目标框架版本 3.5
  • 将 C# 包装器代码文件添加到项目根目录
  • 将以下库引用和命名空间添加到 C# 包装器文件:
using System;
using System.Runtime.InteropServices;
namespace CSharpExampleLib {
...
}

生成两个发布 DLL

  • 将两个项目的生成设置设置为"发布/x86
  • ">
  • 将 C# 生成的目标设置为C++生成的目标
  • 生成
  • 解决方案(生成两个 DLL,每个项目一个(
  • 使用依赖关系查看器确认 DLL 不会将彼此视为缺失(参考(
  • 用于强制 C# DLL 为 32 位CorFlags(参考((这不起作用/不适用于C++ DLL(

将 DLL 添加到 Unity 项目

  • 使用简单的单声道脚本在 Unity 4 (Pro( 中创建一个新项目
  • 关闭 Unity 项目
  • 将 DLL 复制到资产/插件文件夹中
  • 重新打开 Unity 项目(可识别 DLL(
  • 右键单击项目层次结构中的资产,选择"与 MonoDevelopment 同步..."(在 MonoDevelop中打开简单的脚本,确保 DLL 是可访问的(
  • 添加了对简单脚本的库引用:
using System.Runtime.InteropServices;
using System.IO;

从 DLL 调用方法

最后,我添加了从简单脚本到 C# DLL 的日志记录调用(智能感知确认 DLL 和方法可访问(:

Debug.Log(CSharpExampleLib.example.fact(3));
// should log the result of 3 factorial

运行时错误

但是,当我从 Unity 编辑器启动游戏时,出现以下错误:

DllNotFoundException: example
CSharpExampleLib.examplePINVOKE+SWIGExceptionHelper..cctor ()
Rethrow as TypeInitializationException: An exception was thrown by the type initializer for SWIGExceptionHelper
CSharpExampleLib.examplePINVOKE..cctor ()
Rethrow as TypeInitializationException: An exception was thrown by the type initializer for CSharpExampleLib.examplePINVOKE
CSharpExampleLib.example.fact (Int32 n)
SimpleController.Start () (at Assets/scripts/SimpleController.cs:10)

我多次尝试纠正此错误的常见原因(构建为发布,构建为32位,检查依赖沃克等(无济于事。我是否缺少特定于SWIG或Unity的内容?我可以对我的 DLL 执行任何其他检查吗?

在讨论 SWIG 用户邮件列表并仔细查看后,我发现我缺少两个配置步骤:

  1. C++ DLL 必须与 SWIG 接口文件中指定的模块名称具有相同的名称(因此对于使用接口文件 example.i 的玩具示例,最好将C++项目命名为"example",它将生成 example.dll(

  2. 在解决其他问题的前后过程中,我丢失了对自动生成的C++包装器 (example_wrap.cxx( 的引用,需要将其重新添加到C++项目中。