0

背景:我正在为 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

统一版本:2020.3.13f1 LTS

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

4

1 回答 1

0

使用这些头文件时,您的库可能最终依赖于其他一些 .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 文件的信息,并在您尝试调用插件时向您显示无法加载的内容。

于 2021-07-30T23:34:25.137 回答