Build C++ plugin for Unity
You are trying to load UWP plugin in a non UWP environment and this is because of the way you build your dll.
This post describes how to create, compile and build C++ plugin in Unity.
Software version used for this (should work for other older versions too. This information is mentioned just in case there is an update and different UI in the future):
Microsoft Visual Studio 2015
Unity 2017.2.0f3
1.Go to File ---> New ---> Project...
2. Go to Installed --> Templates ---> Visual C++ then Win32 Console Application. Type the name of the project then click Ok.
3.Click Next instead of Finish:
4.Select DLL and unselect Precompiled header then click finish:
5.You can now create your source(.cpp) and header(.h) files.
A.Create a source file:
This should be placed in the Source Files folder. Right click on Source Files ---> Add---> New Item...
B.Select C++ File(.cpp), type the name of the file "FirstDLL.cpp" then click Add.
Example C++ test source:
#include "FirstDLL.h"
int add(int num1, int num2)
{
return num1 + num2;
}
int multiply(int num1, int num2)
{
return num1 * num2;
}
int substract(int num1, int num2)
{
return num1 - num2;
}
int divide(int num1, int num2)
{
return num1 / num2;
}
A.Create a header file:
This should be placed in the Header Files folder. Right click on Header Files ---> Add---> New Item...
B.Select Header File(.h), type the name of the file "FirstDLL.h" then click Add.
Example corresponding header:
#ifndef FIRSTDLL_NATIVE_LIB_H
#define FIRSTDLL_NATIVE_LIB_H
#define DLLExport __declspec(dllexport)
extern "C"
{
DLLExport int add(int num1, int num2);
DLLExport int multiply(int num1, int num2);
DLLExport int substract(int num1, int num2);
DLLExport int divide(int num1, int num2);
}
#endif
That's it. You can now write your C++ plugins code there.
6.Make sure to set the build to release and the platform to 64 bit
If using 32-bit, set the platform to x86.
7.Building plugin:
Go to Build ---> Build Solution
8.Importing into Unity:
PC, Mac & Linux Standalone:
Put the 64-bit dll file into Assets/Plugins
folder.
If you just want to support 32-bit then put the plugin in Assets/Plugins/x86
.
If you want to support universal (both 32-bit and 64-bit platform) then build the dll as such and put it in the Assets/Plugins/x86_64
folder.
Android:
Can be build from Android Studio.
To build from Visual Studio:
A.Go to File ---> New ---> Project...
B. Go to Installed --> Templates ---> Visual C++ then Cross Platform. Click on Install Android support for C++ (Update x). then follow direction to install it.
C. Go to Installed --> Templates ---> Visual C++ ---> Cross Platform. then Android. Select Dynamic Shard Library (Android) then type the name of the project and click Ok. Now, you can jump back to step #5 to continue coding in C++.
Put the Android plugin file (not dll) into the Assets/Plugins/Android
folder.
The supported C++ plugin extension .so
.
Note: If the name of the Android plugin is libFirstDLL-lib.so
, remove the lib
prefix and the .so
when referencing it from C#.In this case, it would be [DllImport("FirstDLL-lib")]
unlike what it would have been in #9.
If you have both armeabi-v7a
and x86
Android .so
plugins then put them in Assets\Plugins\Android\libs\armeabi-v7a
and Assets\Plugins\Android\libs\x86
folders respectively.
iOS
Can be build from Xcode or include the source file into Unity. You can also create it with visual Studio too. Just follow the Android step above but use Install iOS support for C++ (Update x) this time instead of Install Android support for C++ (Update x). Note that you need Mac computer to build for iOS or use virtual machine. Once you do this, follow this Microsoft instruction to finish the setup so that Visual Studio can communicate and build the project on your Mac OS.
Put the iOS plugin file (not dll) into the Assets/Plugins/iOS
folder. The supported plugins extension are .a
, .m
, .mm
, .c
, .cpp
.
Must use [DllImport ("__Internal")]
instead of [DllImport("PluginName")]
or [DllImport("FirstDLL")]
as seen below in #9.
9.Calling C++ function from Unity/C#:
[DllImport("FirstDLL")]
public static extern int add(int num1, int num2);
[DllImport("FirstDLL")]
public static extern int multiply(int num1, int num2);
[DllImport("FirstDLL")]
public static extern int substract(int num1, int num2);
[DllImport("FirstDLL")]
public static extern int divide(int num1, int num2);
void Start()
{
Debug.Log("Add: " + add(10, 2));
Debug.Log("Multiply: " + multiply(10, 2));
Debug.Log("Substract: " + substract(10, 2));
Debug.Log("Divide: " + divide(10, 2));
}
Output:
10.TROUBLESHOOTING PLUGIN ERRORS:
1.Getting the error:
DllNotFoundException:
Solution 1:
The name of the DLL specified in DllImport
does not match the Dll name. Make sure they match by renaming them then restart Unity.
Solution 2:
The DLL is placed in the wrong folder. The folder must be named Assets/Plugins
. The spelling is also case sensitive.
2.Getting the error:
EntryPointNotFoundException:
Solution 1:
The function name declared DllImport
doesn't exist or match with the one declared on the C++ side. Make sure that the spellings are the-same on both sides. The spelling is also case sensitive.
Solution 2:
The C++ DLL functions are not being included in the C++ plugin. On Windows, dllexport
is used to make these function export themselves in the DLL. This is not required in other platforms or OS. This is usually done in the header file only to keep the source file clean. See example in the header file above or screenshot below.
Solution 3:
You compiler is renaming the C++ functions. You can prevent this by enclosing them with the extern
keyword. Again, see example in the header file above or screenshot below:
2.Getting no error but incorrect or wired result:
Solution 1:
The parameter doesn't match. Make sure that the parameter of the function on the C++ and C# side match and have the-same amount of parameter. Also the datatype must match. If they don't, expect undefined behavior.
How to build an objective-C native plugin in unity for appleTV and MacOSX
If you want to use your Objective-C (.mm) to implement the Mac OS plug-in for unity, you should deploy it as a bundle.
To create the bundle project with XCode:
Open XCode.
Select File > New > Project > macOS > Framework & Library > Bundle.
Build asimple c++ static library of ios(for unity), but cannot find the .a file
Solution is very simple, I create a new project, add the example.hpp and example.cpp into the project, set build target to ios only, click build, then the .a file is generated, I don't know why this happen, maybe some manipulation ruin the settings.
How to build plugin by Xcode include OpenCV library (or another 3rd party library) to give Unity to use?
Finally, I try this method and successfully build .bundle
which include another 3rd party library to give Unity to use.
Let me take the OpenCV library an example.
First, click project
and you can see the Build Setting
button. Click it and modify Header Search Paths
and Library Search Paths
. In my case, I enter /usr/local/Cellar/opencv/3.4.3/include/**
and /usr/local/Cellar/opencv/3.4.3/lib/**
, then, click targets
and do the same things.
Also, we need to add OpenCV library in the project because unity couldn’t dynamically call the 3rd part library in the plugin when it runs. So, you need to package them and then Xcode will automatically make the framework.
So, click the Build Phases
button. Now, you can see Link Binary With Libraries
in this page and then click the +
button and click add other...
. Then, go to your OpenCV library path
/usr/local/Cellar/opencv/3.4.3/lib (For my case)
Select all of the files without "pythonx.x".
Now, you should see the Frameworks
list in your Xcode IDE and then you can do some test and check that add 3rd party library successful or not.
c++:
int ProcessImage()
{
cv::Mat test(10, 10, CV_8UC1); //use opencv library
return test.rows; // should return 10
}
c++ Header
#include <opencv2/imgproc.hpp>
#include <stdio.h>
extern "C"
{
int ProcessImage();
}
c#
[DllImport("test")] /*the name of Plugin is Test*/
private static extern int ProcessImage();
Debug.Log(ProcessImage().ToString());
Result
Related Topics
File Exists by File Name Pattern
Multiple Insert Statements in One Connection
Reading/Writing from Named Pipes Under Mono/Linux
How to Code a Progress Bar for Windows 7 to Also Update Itself on the Taskbar
Search Xdocument Using Linq Without Knowing the Namespace
Webutility.HTMLdecode Vs Httputilty.HTMLdecode
Easiest Way to Rotate a List in C#
Is There Pointer in C# Like C++? Is It Safe
HTML5 Email Input Cannot Assign Id and Runat="Server" ASP.NET 4
Webapi Cannot Parse Multipart/Form-Data Post
Using Getproperties() with Bindingflags.Declaredonly in .Net Reflection
What Is the Fastest Way to Compute Sin and Cos Together
How Does Java's Use-Site Variance Compare to C#'s Declaration Site Variance
In C# Wpf, Why Is My Tabcontrol's Selectionchanged Event Firing Too Often