我的目标是获得一个使用 SWIG 包装的玩具 C++ 库,并且可供 Unity 中的 C#/Mono 脚本访问。 (换句话说,让库功能在 Windows 版本的游戏中运行。接下来我将处理 Android :)
我一直在关注 Build a C# module 的组合(痛饮教程),Unity and DLLs (埃里克·伊斯特伍德)和 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 的接口(interface)文件)
- 为接口(interface)文件创建自定义构建工具
- 执行自定义构建工具(为 C++ 和 C# 生成包装代码)
- 将C++包装代码添加到项目中(稍后用于生成C++ DLL)
创建 C# 项目
- 在 Visual Studio 中创建 C# 类库项目
- 更改目标框架 3.5 版
- 将 C# 包装器代码文件添加到项目根目录
- 将以下库引用和命名空间添加到 C# 包装器文件:
using System;
using System.Runtime.InteropServices;
namespace CSharpExampleLib {
...
}
构建两个 Release DLL
- 将两个项目的build设置设为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)
- 右键单击项目层次结构中的 Assets ,选择“与 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 执行任何其他检查吗?
最佳答案
经过讨论SWIG user mailing list仔细检查后,我发现我缺少两个配置步骤:
C++ DLL 的名称必须与 SWIG 接口(interface)文件中指定的模块名称相同(因此对于我使用接口(interface)文件 example.i 的玩具示例,最好将 C++ 项目命名为“example”,并且它会生成example.dll)
在解决其他问题的过程中,我丢失了对自动生成的 C++ 包装器 (example_wrap.cxx) 的引用,需要将其重新添加到 C++ 项目中。
关于c# - 如何在 Unity 3D 中包含 SWIG 封装的 C++?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27534054/