Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How can I include SWIG-wrapped C++ in Unity 3D?

My goal is to get a toy C++ library wrapped using SWIG, and accessible to C# / Mono scripts in Unity. (In other words, have the library functionality working in a Windows build of the game. I'll tackle Android next :)

I have been following a combination of Build a C# module (SWIG tutorial), Unity and DLLs (Eric Eastwood) and Getting started with SWiG for Visual Studio projects (Technical Recipes). I have generated two DLLs in Visual Studio 2013 and added them to the Unity project. But accessing the toy method at runtime is failing.


Steps I followed (including common fixes for the error I am receiving):

Create C++ project / custom build

  • Create a C++ Win32 Console Application project in Visual Studio
    • (because MonoDevelop on Windows cannot compile C++)
  • Add example code to the project
  • Create example.i (interface file for SWIG)
  • Create an Custom Build Tool for the interface file
  • Execute the Custom Build Tool (generates wrapper code for C++ and C#)
  • Add C++ wrapper code to project (will be used later to generate C++ DLL)

Create C# project

  • Create a C# Class Library project in Visual Studio
  • Change Target Framework version 3.5
  • Add C# wrapper code files to project root
  • Add the following library references and namespace to the C# wrapper files:
using System;
using System.Runtime.InteropServices;

namespace CSharpExampleLib {
...
}

Build two Release DLLs

  • Set the build settings to Release / x86 for both projects
  • Set the target for the C# build to the target of the C++ build
  • Build the solution (generates two DLLs, one per project)
  • Confirm with Dependency Walker that the DLLs do not see each other as missing (reference)
  • Used CorFlags to force the C# DLL to be 32-bit (reference) (this does not work / does not apply to C++ DLL)

Add DLLs to Unity project

  • Create a new project in Unity 4 (Pro) with a simple Mono script
  • Close Unity project
  • Copy the DLLs into Assets/Plugins folder
  • Reopen the Unity project (DLLs recognised)
  • Right-click on Assets in the Project Hierarchy, select "Synch with MonoDevelop..." (opens simple script in MonoDevelop, ensures DLLs are accessible)
  • Added library references to the simple script:
using System.Runtime.InteropServices;
using System.IO;

Invoke method from DLL

Finally, I added a logging call from the simple script to the C# DLL (Intellisense confirms that the DLL and method are accessible):

Debug.Log(CSharpExampleLib.example.fact(3));
// should log the result of 3 factorial

Runtime error

However, when I start the game from the Unity editor, I get the following error:

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)

I made several attempts to correct common causes for this error (build as Release, build as 32-bit, check Dependency Walker, etc) to no avail. Is there something SWIG- or Unity-specific I am missing? Any other checks I can perform on my DLLs?

like image 259
Katherine Rix Avatar asked Dec 17 '14 20:12

Katherine Rix


People also ask

Can you write C in Unity?

The language that's used in Unity is called C# (pronounced C-sharp). All the languages that Unity operates with are object-oriented scripting languages. Like any language, scripting languages have syntax, or parts of speech, and the primary parts are called variables, functions, and classes.

How do I open C scripts in Unity?

Open Unity scripts in Visual Studio Once Visual Studio is set as the external editor for Unity, double-clicking a script from the Unity editor will automatically launch or switch to Visual Studio and open the chosen script.

Can I use C++ in Unity engine?

Both Unity and UnrealEngine utilize C++ in their source code: Unity is partially written using C++ and C#, whereas Unreal Engine is written in C++ entirely. C++ is widely used to develop high-tier game engines and critical service applications where optimal resource utilization and performance are a priority.

What is swig C++?

SWIG is a software development tool that connects programs written in C and C++ with a variety of high-level programming languages. SWIG is used with different types of target languages including common scripting languages such as Javascript, Perl, PHP, Python, Tcl and Ruby.


1 Answers

After discussion on the SWIG user mailing list and some careful review, I discovered I was missing two configuration steps:

  1. The C++ DLL must have the same name as the module name specified in the SWIG interface file (so for my toy example using interface file example.i, it is best to name the C++ project "example" and it will generate example.dll)

  2. In the backwards and forwards of resolving other issues, I lost the reference to the autogenerated C++ wrapper (example_wrap.cxx) and needed to re-add it to the C++ project.

like image 86
Katherine Rix Avatar answered Sep 23 '22 18:09

Katherine Rix