草庐IT

c# - 为Unity构建C++插件

coder 2024-02-14 原文

尝试创建我的第一个插件。
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时提及此信息):

  • Microsoft Visual Studio 2015
  • Unity 2017.2.0f3

  • 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-v7ax86 Android .so插件,则分别将它们放在Assets\Plugins\Android\libs\armeabi-v7aAssets\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/

    有关c# - 为Unity构建C++插件的更多相关文章

    1. ruby - 如何每月在 Heroku 运行一次 Scheduler 插件? - 2

      在选择我想要运行操作的频率时,唯一的选项是“每天”、“每小时”和“每10分钟”。谢谢!我想为我的Rails3.1应用程序运行调度程序。 最佳答案 这不是一个优雅的解决方案,但您可以安排它每天运行,并在实际开始工作之前检查日期是否为当月的第一天。 关于ruby-如何每月在Heroku运行一次Scheduler插件?,我们在StackOverflow上找到一个类似的问题: https://stackoverflow.com/questions/8692687/

    2. ruby-on-rails - 无法使用 Rails 3.2 创建插件? - 2

      我对最新版本的Rails有疑问。我创建了一个新应用程序(railsnewMyProject),但我没有脚本/生成,只有脚本/rails,当我输入ruby./script/railsgeneratepluginmy_plugin"Couldnotfindgeneratorplugin.".你知道如何生成插件模板吗?没有这个命令可以创建插件吗?PS:我正在使用Rails3.2.1和ruby​​1.8.7[universal-darwin11.0] 最佳答案 随着Rails3.2.0的发布,插件生成器已经被移除。查看变更日志here.现在

    3. ruby-on-rails - 如何优雅地重启 thin + nginx? - 2

      我的瘦服务器配置了nginx,我的ROR应用程序正在它们上运行。在我发布代码更新时运行thinrestart会给我的应用程序带来一些停机时间。我试图弄清楚如何优雅地重启正在运行的Thin实例,但找不到好的解决方案。有没有人能做到这一点? 最佳答案 #Restartjustthethinserverdescribedbythatconfigsudothin-C/etc/thin/mysite.ymlrestartNginx将继续运行并代理请求。如果您将Nginx设置为使用多个上游服务器,例如server{listen80;server

    4. c# - 如何在 ruby​​ 中调用 C# dll? - 2

      如何在ruby​​中调用C#dll? 最佳答案 我能想到几种可能性:为您的DLL编写(或找人编写)一个COM包装器,如果它还没有,则使用Ruby的WIN32OLE库来调用它;看看RubyCLR,其中一位作者是JohnLam,他继续在Microsoft从事IronRuby方面的工作。(估计不会再维护了,可能不支持.Net2.0以上的版本);正如其他地方已经提到的,看看使用IronRuby,如果这是您的技术选择。有一个主题是here.请注意,最后一篇文章实际上来自JohnLam(看起来像是2009年3月),他似乎很自在地断言RubyCL

    5. C# 到 Ruby sha1 base64 编码 - 2

      我正在尝试在Ruby中复制Convert.ToBase64String()行为。这是我的C#代码:varsha1=newSHA1CryptoServiceProvider();varpasswordBytes=Encoding.UTF8.GetBytes("password");varpasswordHash=sha1.ComputeHash(passwordBytes);returnConvert.ToBase64String(passwordHash);//returns"W6ph5Mm5Pz8GgiULbPgzG37mj9g="当我在Ruby中尝试同样的事情时,我得到了相同sha

    6. ruby - 在 Ruby 中构建长字符串的简洁方法 - 2

      在编写Ruby(客户端脚本)时,我看到了三种构建更长字符串的方法,包括行尾,所有这些对我来说“闻起来”有点难看。有没有更干净、更好的方法?变量递增。ifrender_quote?quote="NowthatthereistheTec-9,acrappyspraygunfromSouthMiami."quote+="ThisgunisadvertisedasthemostpopularguninAmericancrime.Doyoubelievethatshit?"quote+="Itactuallysaysthatinthelittlebookthatcomeswithit:themo

    7. ruby - 使用 `+=` 和 `send` 方法 - 2

      如何将send与+=一起使用?a=20;a.send"+=",10undefinedmethod`+='for20:Fixnuma=20;a+=10=>30 最佳答案 恐怕你不能。+=不是方法,而是语法糖。参见http://www.ruby-doc.org/docs/ProgrammingRuby/html/tut_expressions.html它说Incommonwithmanyotherlanguages,Rubyhasasyntacticshortcut:a=a+2maybewrittenasa+=2.你能做的最好的事情是:

    8. Unity 热更新技术 | (三) Lua语言基本介绍及下载安装 - 2

      ?博客主页:https://xiaoy.blog.csdn.net?本文由呆呆敲代码的小Y原创,首发于CSDN??学习专栏推荐:Unity系统学习专栏?游戏制作专栏推荐:游戏制作?Unity实战100例专栏推荐:Unity实战100例教程?欢迎点赞?收藏⭐留言?如有错误敬请指正!?未来很长,值得我们全力奔赴更美好的生活✨------------------❤️分割线❤️-------------------------

    9. FOHEART H1数据手套驱动Optitrack光学动捕双手运动(Unity3D) - 2

      本教程将在Unity3D中混合Optitrack与数据手套的数据流,在人体运动的基础上,添加双手手指部分的运动。双手手背的角度仍由Optitrack提供,数据手套提供双手手指的角度。 01  客户端软件分别安装MotiveBody与MotionVenus并校准人体与数据手套。MotiveBodyMotionVenus数据手套使用、校准流程参照:https://gitee.com/foheart_1/foheart-h1-data-summary.git02  数据转发打开MotiveBody软件的Streaming,开始向Unity3D广播数据;MotionVenus中设置->选项选择Unit

    10. unity---接入Admob - 2

      目录1.AdmobSDK下载地址2.将下载好的unityPackagesdk导入到unity里​编辑 3.解析依赖到项目中

    随机推荐