1

我们的 Unity3D 游戏为我们框架的一部分使用了 C++ DLL,并且它在 Windows 中对我们来说一切正常。我们最近尝试为 Linux 构建我们的游戏,但遇到了非常严重的硬崩溃。

我将问题与 Unity3D 本身隔离开来 -> 在没有我们的 C++ 库的情况下,它在 Windows 和 Linux 之间运行得非常好。

我已将该库编译为 Ubuntu x64 环境中的 Linux 库。

游戏可以正常加载到我们的初始场景中(证明 Unity3D 没问题),但是当我们加载使用库的关卡时,当使用从 Unity3D 传递的数据调用其中一个库函数时,我们会遇到内存错误的段错误。

我编译了该库的调试版本并在 Linux 的 gdb 中运行游戏以生成以下调试调用堆栈:

Program received signal SIGSEGV, Segmentation fault.
[Switching to Thread 0x7ffff7fd3780 (LWP 7347)]
0x00007fffb42d94da in geom::Vector3f::Vector3f (this=0x1adff9a8, other=...)
    at /mnt/hgfs/WFTO/war-for-the-overworld/CustomPlugins/GameLogic/GameLogic/Source/lib/geom/Vector3f.h:16
16/mnt/hgfs/WFTO/war-for-the-overworld/CustomPlugins/GameLogic/GameLogic/Source/lib/geom/Vector3f.h: No such file or directory.
(gdb) 
Continuing.

Program received signal SIGABRT, Aborted.
0x00007ffff6236425 in raise () from /lib/x86_64-linux-gnu/libc.so.6
(gdb) bt
#0  0x00007ffff6236425 in raise () from /lib/x86_64-linux-gnu/libc.so.6
#1  0x00007ffff6239b8b in abort () from /lib/x86_64-linux-gnu/libc.so.6
#2  0x00007ffff2749f6c in ?? () from /home/ryan/.gvfs/build on strich/Release/Linux/WFTO_Data/Mono/x86_64/libmono.so
#3  0x00007ffff27876e9 in ?? () from /home/ryan/.gvfs/build on strich/Release/Linux/WFTO_Data/Mono/x86_64/libmono.so
#4  <signal handler called>
#5  0x00007fffb42d94da in geom::Vector3f::Vector3f (this=0x1adff9a8, other=...)
    at /mnt/hgfs/WFTO/war-for-the-overworld/CustomPlugins/GameLogic/GameLogic/Source/lib/geom/Vector3f.h:16
#6  0x00007fffb42db207 in data::LocatedObject::LocatedObject (this=0x1adff920, id=48, clientObject=0x23, 
    ownerPlayerNumber=0, location=...)
    at /mnt/hgfs/WFTO/war-for-the-overworld/CustomPlugins/GameLogic/GameLogic/Source/components/data/abstract/LocatedObject.h:23
#7  0x00007fffb42db75e in data::PhysicalObject::PhysicalObject (this=0x1adff920, id=48, clientObject=0x23, 
    ownerPlayerNumber=0, location=..., bounds=..., orientation=..., collisionType=data::COLLISION_FULL_SOLID)
    at /mnt/hgfs/WFTO/war-for-the-overworld/CustomPlugins/GameLogic/GameLogic/Source/components/data/abstract/PhysicalObject.h:40
#8  0x00007fffb42e443c in data::PropData::PropData (this=0x1adff920, id=48, clientObject=0x23, ownerPlayerNumber=0, 
    location=..., bounds=..., orientation=...)
    at /mnt/hgfs/WFTO/war-for-the-overworld/CustomPlugins/GameLogic/GameLogic/Source/components/data/prop/PropData.h:18
#9  0x00007fffb42b6e0d in data_PropData_new (id=48, clientObject=0x23, ownerPlayerNumber=0, 
    location=<error reading variable: Cannot access memory at address 0x4208cccd429acccd>, 
    bounds=<error reading variable: Cannot access memory at address 0x3f666666>, 
    orientation=<error reading variable: Cannot access memory at address 0x1cb3>)
    at /mnt/hgfs/WFTO/war-for-the-overworld/CustomPlugins/GameLogic/GameLogic/Source/components/data/prop/PropData_export.h:32

基于上述,它非常清楚根本原因在哪里。当调用data_PropData_new时,我们的库正在获取指向传递给函数的某些参数的错误内存指针。这是 C++ 函数头:

extern "C" { 
DLL_EXPORT PropData* data_PropData_new(
    long long id, ManagedReference clientObject, int ownerPlayerNumber,
    geom::Vector3f location, geom::Vector3f bounds, geom::Vector3f orientation)

C# DllImport:

[DllImport("GameLogic", EntryPoint = "data_PropData_new", CallingConvention = CallingConvention.Cdecl)]
        internal static extern NativePropData create(
        long id, IntPtr clientObject, int ownerPlayerNumber,
        Vector3f location, Vector3f bounds, Vector3f orientation);

首先要注意的是,所有geom::Vector3f类型的参数都存在错误的内存。好的,很好,这是一个很好的线索。下面是C++ 和 C#的Vector3f代码:

Vector3f.h(相当大,所以我粘贴了它)。

Vector3f.cs(相当大,所以我粘贴了它)。

重要的是要注意这个库在 Windows 中工作得非常好。但不是Linux。会不会是在 Linux 下 Vector3f 数据没有被正确地固定在内存中?我有一种预感,在 Vector3f 上存在一些特定于 Mono InteropServices 平台的编组问题,但我正在努力找出原因和位置。

4

0 回答 0