【问题标题】:How can I include SWIG-wrapped C++ in Unity 3D?如何在 Unity 3D 中包含 SWIG 包装的 C++?
【发布时间】:2015-02-16 12:01:23
【问题描述】:

我的目标是获得一个使用 SWIG 包装的玩具 C++ 库,并且可以在 Unity 中访问 C#/Mono 脚本。 (换句话说,让库功能在 Windows 版本的游戏中运行。接下来我将处理 Android :)

我一直在关注Build a C# module(SWIG 教程)、Unity and DLLs(Eric Eastwood)和Getting started with SWiG for Visual Studio projects(技术食谱)的组合。我在 Visual Studio 2013 中生成了两个 DLL,并将它们添加到 Unity 项目中。但是在运行时访问 toy 方法失败了。


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

创建 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

  • 将两个项目的构建设置设置为 Release / x86
  • 将 C# 构建的目标设置为 C++ 构建的目标
  • 构建解决方案(生成两个 DLL,每个项目一个)
  • 与 Dependency Walker 确认 DLL 不会将彼此视为丢失 (reference)
  • 使用 CorFlags 强制 C# DLL 为 32 位 (reference)(这不起作用/不适用于 C++ DLL)

将 DLL 添加到 Unity 项目

  • 使用简单的 Mono 脚本在 Unity 4 (Pro) 中创建一个新项目
  • 关闭 Unity 项目
  • 将 DLL 复制到 Assets/Plugins 文件夹中
  • 重新打开 Unity 项目(已识别 DLL)
  • 右键单击 Project Hierarchy 中的 Assets,选择“Synch with MonoDevelop...”(在 MonoDevelop 中打开简单脚本,确保 DLL 可访问)
  • 为简单脚本添加了库引用:
using System.Runtime.InteropServices;
using System.IO;

从 DLL 调用方法

最后,我从简单脚本向 C# DLL 添加了一个日志调用(Intellisense 确认 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)

我多次尝试纠正此错误的常见原因(构建为 Release、构建为 32 位、检查 Dependency Walker 等),但均无济于事。我是否缺少特定于 SWIG 或 Unity 的东西?我可以对我的 DLL 执行任何其他检查吗?

【问题讨论】:

    标签: c# c++ dll unity3d swig


    【解决方案1】:

    在讨论SWIG user mailing list 并仔细查看后,我发现我缺少两个配置步骤:

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

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

    【讨论】:

    • 嗨,Katherine,您是否设法为 Android 做同样的事情,即使用为 Android 构建的 SO 并通过使用 SWIG 生成的胶水代码与 SO 对话的 Unity 游戏?所有官方 Unity 示例似乎都展示了如何编写胶水代码的 C# 部分,但就我而言,我已经有了 SWIG 生成的 C# 代码,我只是在寻找一种加载 SO 文件的方法
    • @Harkish 不,我的老板对最初的 RnD 很满意,我被转移到其他事情上。您是否尝试过将 SO 添加到 Assets->Plugins->Android 文件夹,然后转到 swig 生成的 c# 并在任何声明上方添加 import 语句? (我从 Unity 文档的“使用 C# 中的插件”小节中得到这个:docs.unity3d.com/Manual/PluginsForAndroid.html
    猜你喜欢
    • 2011-02-10
    • 2021-08-29
    • 1970-01-01
    • 2021-05-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多