尝试创建我的第一个插件。 cpp代码是:
头:
#pragma once
#ifndef __MY_DLL_H
#define __MY_DLL_H
extern "C" int add_1(int number);
#endif
源:
//FirstDLL.cpp
#include "FirstDLL.h"
extern "C" int add_1(int number) {
return number + 1;
}
然后我编译并将DLL放在Assets/Plugins
文件夹中,dll文件为FirstDLL.dll
。从统一方面来说,我有一个简单的C#脚本用于组件:
using UnityEngine;
public class MyBehaviour : MonoBehaviour {
// Use this for initialization
[Header("Nuts!")]
public int my_curr_val;
void Start () {
}
// Update is called once per frame
void Update () {
print(add_1(my_curr_val));
}
[DllImport("FirstDLL")]
public static extern int add_1(int number);
}
但是当我尝试运行脚本时,我收到以下错误:
插件:无法加载'资产/插件/ FirstDLL.dll'有错误 '此操作仅在应用容器的上下文中有效。 &#39 ;. 插件:无法加载'资产/插件/ FirstDLL.dll'错误'此操作仅在应用容器的上下文中有效。 &#39 ;. DllNotFoundException:FirstDLL MyBehaviour.Update()(在Assets / MyBehaviour.cs:17)
文档似乎很差,有什么建议吗? 有this answer,但不确定我做错了什么。我试图创建几个解决方案(Windows通用平台,Windows 8.1等)仍然无法正常工作。
答案 0 :(得分:7)
您正在尝试在非UWP环境中加载UWP插件,这是因为您构建dll的方式。
这篇文章描述了如何在Unity中创建,编译和构建C ++插件。
用于此目的的软件版本(也适用于其他旧版本。如果将来有更新和不同的用户界面,则会提及此信息):
Microsoft Visual Studio 2015
Unity 2017.2.0f3
1 。转到文件 ---> 新 ---> 项目...
<强> 2 即可。转到已安装 - &gt; 模板 ---&gt; Visual C ++ 然后 Win32控制台应用程序。输入项目名称,然后单击“确定”。
3 。点击下一步而不是完成:
4 。选择 DLL 并取消选择预编译标题,然后点击完成:
5 。您现在可以创建源(.cpp)和标题(.h)文件。
A 。创建源文件:
这应该放在源文件文件夹中。右键单击Source Files ---&gt;添加---&GT;新项目......
B 。选择C ++文件(.cpp),输入文件的名称&#34; FirstDLL.cpp&#34;然后单击添加。
示例C ++测试源:
#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 。创建一个头文件:
这应该放在页眉文件文件夹中。右键单击Header Files ---&gt;添加---&GT;新项目......
B 。选择头文件(.h),输入文件的名称&#34; FirstDLL.h&#34;然后单击添加。
示例相应的标题:
#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
那就是它。您现在可以在那里编写C ++插件代码。
6 。确保将版本设置为发布版并将平台设置为64位
如果使用32位,请将平台设置为x86。
7 。构建插件:
转到构建 ---&gt; 构建解决方案
8 。导入Unity:
PC,Mac&amp; Linux Standalone :
将64位dll文件放入Assets/Plugins
文件夹。
如果您只想支持32位,请将插件放入Assets/Plugins/x86
。
如果要支持通用(32位和64位平台),请构建dll并将其放在Assets/Plugins/x86_64
文件夹中。
<强>的Android :
可以从 Android Studio 构建。
从Visual Studio构建:
A 。转到文件 ---&gt; 新 ---&gt; 项目...
<强>乙即可。转到已安装 - &gt; 模板 ---&gt; Visual C ++ 然后跨平台。单击安装Android支持C ++(更新x)。然后按照指示安装它。
<强> C 即可。转到已安装 - &gt; 模板 ---&gt; Visual C ++ ---&gt; 跨平台。然后 Android 。选择动态分片库(Android),然后键入项目名称,然后单击“确定”。现在,您可以跳回到步骤#5 继续使用C ++进行编码。
将Android插件文件(不是dll)放入Assets/Plugins/Android
文件夹。
支持的C ++插件扩展.so
。
注意:如果Android插件的名称为libFirstDLL-lib.so
,请在从C#引用时删除lib
前缀和.so
。在这种情况下,它将是[DllImport("FirstDLL-lib")]
,与#9中的情况不同。
如果您同时拥有armeabi-v7a
和x86
个Android .so
插件,请分别将它们放入Assets\Plugins\Android\libs\armeabi-v7a
和Assets\Plugins\Android\libs\x86
个文件夹中。
<强>的iOS
可以从 Xcode 构建,也可以将源文件包含在Unity中。您也可以使用Visual Studio创建它。只需按照上面的Android步骤操作,但这次使用安装iOS支持C ++(更新x),而不是安装Android支持C ++(更新x)。请注意,您需要使用Mac计算机为iOS构建或使用虚拟机。完成此操作后,请按照this Microsoft指令完成设置,以便Visual Studio可以在Mac OS上进行通信和构建项目。
将iOS插件文件(不是dll)放入Assets/Plugins/iOS
文件夹。受支持的插件扩展程序为.a
,.m
,.mm
,.c
,.cpp
。
必须使用[DllImport ("__Internal")]
代替[DllImport("PluginName")]
或[DllImport("FirstDLL")]
,如下所示#9 。
9 。从Unity / C#调用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));
}
<强>输出:
10 。疑难解答插件错误:
1 。获取错误:
DllNotFoundException:
解决方案1 :
DllImport
中指定的DLL名称与Dll名称不匹配。通过重命名确保它们匹配,然后重新启动Unity。
解决方案2 :
DLL放在错误的文件夹中。该文件夹必须命名为Assets/Plugins
。拼写也区分大小写。
2 。获取错误:
EntryPointNotFoundException:
解决方案1 :
声明为DllImport
的函数名称不存在或与C ++端声明的函数名称匹配。确保双方的拼写相同。拼写也区分大小写。
解决方案2 :
C ++ DLL函数未包含在C ++插件中。在Windows上,dllexport
用于使这些函数在DLL中自行导出。在其他平台或操作系统中不需要这样做。这通常在头文件中完成,只是为了保持源文件的清洁。请参阅上面的头文件中的示例或下面的屏幕截图。
解决方案3 :
您的编译器正在重命名C ++函数。您可以使用extern
关键字将其括起来以防止这种情况发生。再次,请参阅上面的头文件中的示例或下面的屏幕截图:
2 。没有错误但是错误或有线结果:
解决方案1 :
参数不匹配。确保C ++和C#端的函数参数匹配并具有相同数量的参数。数据类型也必须匹配。如果他们不这样做,则期待未定义的行为。