我的目标是使用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项目中 . 但是在运行时访问玩具方法失败了 .
我遵循的步骤(包括我收到的错误的常见修复):
Create C++ project / custom build
在Visual Studio中创建C Win32控制台应用程序项目
(因为Windows上的MonoDevelop无法编译C)
为项目添加示例代码
创建example.i(SWIG的接口文件)
为接口文件创建自定义构建工具
执行自定义构建工具(为C和C#生成包装器代码)
将C包装器代码添加到项目中(稍后将用于生成C DLL)
Create C# project
在Visual Studio中创建C#类库项目
更改目标框架版本3.5
将C#包装器代码文件添加到项目根目录
将以下库引用和命名空间添加到C#包装器文件中:
using System;
using System.Runtime.InteropServices;
namespace CSharpExampleLib {
...
}
Build two Release DLLs
为两个项目的构建设置设置为Release / x86
将C#构建的目标设置为C构建的目标
构建解决方案(生成两个DLL,每个项目一个)
使用Dependency Walker确认DLL没有看到彼此丢失(reference)
使用 CorFlags 强制C#DLL为32位(reference)(这不起作用/不适用于C DLL)
Add DLLs to Unity project
使用简单的单声道脚本在Unity 4(Pro)中创建一个新项目
关闭Unity项目
将DLL复制到Assets / Plugins文件夹中
重新打开Unity项目(已识别的DLL)
右键单击Project Hierarchy中的Assets,选择"Synch with MonoDevelop..."(在MonoDevelop中打开简单脚本,确保可以访问DLL)
添加了对简单脚本的库引用:
using System.Runtime.InteropServices;
using System.IO;
Invoke method from DLL
最后,我添加了从简单脚本到C#DLL的日志记录调用(Intellisense确认可以访问DLL和方法):
Debug.Log(CSharpExampleLib.example.fact(3));
// should log the result of 3 factorial
Runtime error
但是,当我从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上执行的任何其他检查?