c# - 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
放进去,但没有用。我也尝试更明确地说明头文件的路径,但那里也没有更改。
通常,这会导致我提出以下问题,非常感谢对其中任何一个问题的回答:
- 如何解决由 .so 文件的依赖项引起的这个问题?(理想情况下,不必对头文件本身/位置做很多魔术,因为我希望在不更改当前代码库的情况下实现这一点)
- 有什么办法可以得到更详细的反馈吗?目前似乎错误地构建了 .so 文件,没有在 C# 文件中正确引用它,头文件等问题现在总是导致 DllNotFoundException。最好有一些比所有内容都相同的异常更详细的错误报告。
- 有没有更好/替代的方法来实现我希望在这里做的事情(比如在后台启动可执行文件并从这里提供/推送数据)?
回顾:
操作系统:Ubuntu 20.04
统一版本: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 文件的信息,并在您尝试调用插件时向您显示无法加载的内容。
推荐阅读
- spring-cloud-dataflow - Spring Cloud Stream Source Extension 的命名目的地
- java - GUI程序一旦在java中执行的操作方法中冻结
- bash - 两个看似相同的字符串,但换行符不相等
- arrays - 使用 JSON 和 MySql 将值收集到变量中
- c - 在 C 中创建一个通用的 ArrayLIst
- python - 错误:没有名为枕头、请求或 pywhatkit 的模块
- c++ - 链接器找不到与 C++ 程序连接的汇编函数
- python - numpy 数组列表到一个 numpy 数组
- javascript - 根据字符串数组过滤对象数组
- c# - 在使用omnisharp和roslyn提交之前对c#进行lint?