Unity 插件的 .so 文件:导致 DllNotFoundException 的头文件?

问题描述

背景:我正在为 Unity 中的机器人创建可视化。机器人的软件(以及本例中的模拟器)均在 MATLAB Simulink 模型和 MEX 文件中的 C/C++ 代码中实现。

为了帮助与其他应用程序通信,它们使用共享内存。因此,检索和推送相关数据相当简单,因为只需使用 DB get/put 与本地实时数据库交互即可。为了不了解这里不相关的细节,这导致了一个非常简单的单个 C 文件,我现在只是在其中打印其中一个机器人的 x 和 y 坐标。由于这一切都在 Ubuntu 20.04 上运行,我已将其转换为可执行文件,可以在终端中正确打印机器人位置。

问题:但是,我现在面临着将这些数据导入 Unity 的挑战。我试图从这个 C 文件创建一个 .so 文件,以便它可以用作 Unity 中的插件。但是,我似乎总是收到一条 DllNotFoundException 消息。

为了让您了解我所做的,这里是 C 文件的简化印象:

int end=0;

extern int main(int argc,char *argv[])
{
    while(!end) {
        printf("PosX : %lf\n",(double)xyz[0]);
        printf("PosY : %lf\n",(double)xyz[1]);
        usleep(50000);
    }
    return 0;
}

最初我尝试将其转换为 .so 文件并将其放入 Assets/Plugins/Linux 并在场景中创建了一个包含以下内容的简单脚本:

using System;
using System.Runtime.InteropServices;
using UnityEngine;

public class PluginImportTest : MonoBehavIoUr
{
    [DllImport("TurtlePlugin",CallingConvention = CallingConvention.Cdecl)]
    private static extern int main(int argc,string[] argv);

    void Start()
    {
        string[] argv = {"2"};
        int argc = argv.Length;
        Debug.Log(main(argc,argv));
    }
}

但是我似乎总是得到 DllNotFoundException: <pluginname>。遇到此问题的大多数其他情况似乎在将 .so 文件类型传递到 C# 文件或将其放置在错误文件夹中时包含了该文件类型。

但是非常感谢他们的这个 repo:https://github.com/Unity-Technologies/DesktopSamples 我实际上找到了一个确实有效的例子。以此为基础构建并逐段添加我的代码,我发现一旦我使用包含的头文件中的某些内容,它就会再次开始抛出 DllNotFoundException 。例如,在某些时候,本地 RTDB 通过调用来自 DB_init()rtdb_api.h 进行初始化。此头文件位于 /usr/include/rtdb 中。我也尝试将它放在 /usr/local/include/rtdb 中,但无济于事。我也尝试更明确地说明头文件的路径,但也没有更改。

通常这会引导我提出以下问题,非常感谢您对其中任何一个问题的回答:

  1. 如何解决.so 文件的依赖项引起的这个问题? (理想情况下不必对头文件本身/位置做很多魔术,因为我希望在不更改其当前代码库的情况下实现这一点)
  2. 有什么方法可以获得更详细的反馈吗?目前似乎错误地构建 .so 文件,没有在 C# 文件中正确引用它,头文件等问题现在总是导致 DllNotFoundException。最好有一些更详细的错误报告,而不是所有内容的相同异常。
  3. 是否有更好/替代的方法来实现我希望在此处执行的操作(例如将可执行文件作为后台进程启动并从此处输入/推送数据)?

回顾:

操作系统:Ubuntu 20.04

Unity 版本:2020.3.13f1 LTS

希望使用 .so 文件或其他方法将数据从 C/C++ 文件获取到 Unity 中。当前尝试导致包含的头文件出现问题。

解决方法

使用这些头文件时,您的库可能最终依赖于其他一些 .so 文件。由于 Unity 项目旨在独立工作而不依赖于特定系统上安装的内容(否则,如果您将其移动到另一台机器上,您的游戏就会中断!),除非它们是您项目的一部分,否则它不会加载那些 .so 文件。

有两种方法可以进一步排除故障。首先,您可以使用 objdump 实用程序列出 .so 文件所依赖的库:

objdump -x TurtlePlugin.so | grep NEEDED

其次,您可以使用“LD_DEBUG=libs”环境变量集启动Unity:

LD_DEBUG=libs /Path/To/Unity -projectpath /Path/To/Project

它将打印有关它尝试加载的每个 .so 文件的信息,并显示当您尝试调用插件时加载失败的内容。

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...