【发布时间】: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 执行任何其他检查吗?
【问题讨论】: