c# - 如何在 Unity 3D 中包含 SWIG 封装的 C++?

标签 c# c++ dll unity3d swig

我的目标是获得一个使用 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仔细检查后,我发现我缺少两个配置步骤:

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

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

关于c# - 如何在 Unity 3D 中包含 SWIG 封装的 C++?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27534054/

相关文章:

c++ - 如何正确删除从另一个 DLL 接收的派生对象?

c# - 没有身份验证处理程序配置为验证方案 : Microsoft. AspNet.Identity.External

C# 添加范围列表<List<T>>

c# - 在安装时更改 app.config

c++ - 为什么discard的参数是unsigned long long类型的?

c++ - 如何控制 boost::odeint 中 bulirsch_stoer 方法的顺序?

java - UnsatisfiedLinkError : Native Library C:\Domino\nlsxbe. dll 已加载到另一个类加载器中

c# - 在 C# 应用程序中处理位图

c++ - 跨成员共享对象

c++ - Qt Release构建无法打开DLL