尝试创建我的第一个插件。
cpp代码为:
header :
#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);
}
但是,当我尝试运行脚本时,出现以下错误:
Plugins: Failed to load 'Assets/Plugins/FirstDLL.dll' with error 'This operation is only valid in the context of an app container. '. Plugins: Failed to load 'Assets/Plugins/FirstDLL.dll' with error 'This operation is only valid in the context of an app container. '. DllNotFoundException: FirstDLL MyBehaviour.Update () (at Assets/MyBehaviour.cs:17)
文档似乎很差,有什么建议吗?
有this answer,但不确定我在做什么错。我试图创建几种解决方案(Windows通用平台,Windows 8.1等)仍然无法正常工作。
最佳答案
您正在尝试在非UWP环境中加载UWP插件,这是由于生成dll的方式所致。
这篇文章介绍了如何在Unity中创建,编译和构建C++插件。
用于此目的的软件版本(也应适用于其他较旧的版本。仅在将来有更新和不同的UI时提及此信息):
1 。转到文件--->新建--->项目...
2 。转到已安装->模板---> Visual C++,然后转到Win32控制台应用程序。输入项目的名称,然后单击“确定”。
3 。单击下一步而不是完成:
4 。选择DLL并取消选择Precompiled header ,然后单击完成:
5 。您现在可以创建源文件(.cpp)和 header 文件(.h)。
一个创建一个源文件:
这应该放在源文件文件夹中。右键单击源文件--->添加--->新建项目...
B 。选择C++ File(.cpp),键入文件“FirstDLL.cpp”的名称,然后单击“添加”。
示例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;
}
一个创建一个头文件:
这应该放在 header 文件文件夹中。右键单击头文件--->添加--->新建项目...
B 。选择头文件(.h),键入文件“FirstDLL.h”的名称,然后单击“添加”。
相应的标题示例:
#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 。确保将构建版本设置为release,平台设置为64位
如果使用32位,则将平台设置为x86。
7 .Building插件:
转到构建--->构建解决方案
8 。导入Unity:
PC,Mac和Linux独立:
将64位dll文件放入
Assets/Plugins
文件夹。如果只想支持32位,则将插件放在
Assets/Plugins/x86
中。如果要支持通用(32位和64位平台),则应以这种方式构建dll,并将其放在
Assets/Plugins/x86_64
文件夹中。Android :
可以从 Android Studio 构建。
要从Visual Studio生成:
一个。转到文件--->新建--->项目...
B 。转到已安装->模板---> Visual C++,然后跨平台。单击“安装Android对C++的支持(更新x)”。然后按照说明进行安装。
C 。转到已安装->模板---> Visual C++ --->跨平台。然后是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#端的函数参数匹配,并且具有相同数量的参数。数据类型也必须匹配。如果不这样做,请期待未定义的行为。
关于c# - 为Unity构建C++插件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49793560/