【问题标题】:C++ Nvidia PhysX cannot convert PxFoundation to shared_ptr<>C++ Nvidia PhysX 无法将 PxFoundation 转换为 shared_ptr<>
【发布时间】:2018-08-07 21:03:22
【问题描述】:

我正在尝试创建一个 PxFoundation 并将其保存在我的成员变量“foundation”中,它是一个 std::shared_ptr。然而,在创建对象时,我得到了这个:

C2440: '<function-style-cast>': cannot convert from 'physx::PxFoundation *' to 'std::shared_ptr<physx::PxFoundation>'

如何将 PxCreateFoundation 函数中的原始指针放入 shared_ptr?因为我没有调用任何 PhysX 类的 ctor,所以我不能使用 std::make_shared,所以使用普通的 std::shared_ptr() 构造函数似乎是我唯一的选择?

代码:

#include <memory>
#include <PxPhysics.h>
#include "PhysXErrorCallback.hpp"
#include "PhysXDefaultAllocator.hpp"
#include <foundation/PxFoundationVersion.h>

class PhysicsEngine
{
public:


    PhysicsEngine();

    std::shared_ptr<physx::PxFoundation> foundation;

    static PhysXErrorCallback gDefaultErrorCallback;
    static PhysXDefaultAllocator gDefaultAllocatorCallback;
};

PhysicsEngine::PhysicsEngine()
{
    foundation =  std::shared_ptr<physx::PxFoundation>(PxCreateFoundation(PX_FOUNDATION_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback));
}

编辑: 改完之后

foundation = std::shared_ptr<physx::PxFoundation>(...) 

foundation.reset(...)

它现在给了我这些错误:

1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.12.25827\include\memory(1519): error C2440: '<function-style-cast>': cannot convert from 'physx::PxFoundation *' to 'std::shared_ptr<physx::PxFoundation>'
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.12.25827\include\memory(1519): note: No constructor could take the source type, or constructor overload resolution was ambiguous
1>physicsengine.cpp(25): note: see reference to function template instantiation 'void std::shared_ptr<physx::PxFoundation>::reset<physx::PxFoundation>(_Ux *)' being compiled
1>        with
1>        [
1>            _Ux=physx::PxFoundation
1>        ]
1>physicsengine.cpp(25): note: see reference to function template instantiation 'void std::shared_ptr<physx::PxFoundation>::reset<physx::PxFoundation>(_Ux *)' being compiled
1>        with
1>        [
1>            _Ux=physx::PxFoundation
1>        ]
1>c:\program files (x86)\microsoft visual studio\2017\community\vc\tools\msvc\14.12.25827\include\memory(1519): error C2228: left of '.swap' must have class/struct/union

EDIT2:

以下是 PxCreateFoundation 声明和定义:

PX_C_EXPORT PX_FOUNDATION_API physx::PxFoundation* PX_CALL_CONV
PxCreateFoundation(physx::PxU32 version, physx::PxAllocatorCallback& allocator, physx::PxErrorCallback& errorCallback);

physx::PxFoundation* PxCreateFoundation(physx::PxU32 version, physx::PxAllocatorCallback& allocator,
                                    physx::PxErrorCallback& errorCallback)
{
    return physx::shdfnd::Foundation::createInstance(version, errorCallback, allocator);
}

PxFoundation 类:

/**
\brief Foundation SDK singleton class.

You need to have an instance of this class to instance the higher level SDKs.
*/
class PX_FOUNDATION_API PxFoundation
{
  public:
    virtual void release() = 0;

  protected:
    virtual ~PxFoundation()
    {
    }
};

createInstance 定义:

Foundation* Foundation::createInstance(PxU32 version, PxErrorCallback& errc, PxAllocatorCallback& alloc)
{
//...
    mInstance = reinterpret_cast<Foundation*>(alloc.allocate(sizeof(Foundation), "Foundation", __FILE__, __LINE__));

    if(mInstance)
    {
        PX_PLACEMENT_NEW(mInstance, Foundation)(errc, alloc);
        return mInstance;
    }
//...
}

【问题讨论】:

  • PxCreateFoundation 是如何声明的?请提供最少的可编译代码
  • 我不确定是否允许在此处简单地发布 PhysX 3.4 SDK 的内容。我该怎么办?
  • 发布相关上下文:函数声明,剥离类定义...
  • 好的,我发布了所有相关的 PxFoundation 代码。

标签: c++ pointers shared-ptr smart-pointers physx


【解决方案1】:

好像我发现了错误: PhysX SDK 中的大多数析构函数都是不公开的。因此,尝试使用这些类之一创建智能指针会导致错误。 除了使用原始指针之外,唯一的其他选择是创建自定义删除器:

auto foundation = std::shared_ptr<physx::PxFoundation>(PxCreateFoundation(PX_FOUNDATION_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback), [=](physx::PxFoundation* f)
{
    f->release();
});

【讨论】:

    【解决方案2】:

    您的foundation = 行实际上并未调用构造函数。它试图使用称为“功能转换”或“函数样式转换”(#2 here)的语法将原始指针转换为shared_ptr,然后将结果分配给foundation变量(具有已经默认构建)。这是行不通的,因为shared_ptr 没有来自原始指针的强制转换(以防止它意外地获得不应该拥有的东西的所有权)。

    解决问题的最佳方法是使用构造函数的初始化器列表来实际初始化 foundation 与指针:

    PhysicsEngine::PhysicsEngine() :
    foundation(PxCreateFoundation(PX_FOUNDATION_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback))
    {
      // empty
    }
    

    这会将指针传递给foundation 的构造函数,而不是让foundation 默认构造,然后在构造函数主体中分配给它。但是如果你真的因为某种原因需要赋值,你可以使用reset函数告诉foundation取得指针的所有权:

    PhysicsEngine::PhysicsEngine()
    {
        foundation.reset(PxCreateFoundation(PX_FOUNDATION_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback));
    }
    

    【讨论】:

    • 啊,很高兴知道!我决定采用后一种方法,以防我不想在构造上启动我的物理。但是,它给了我我在问题中编辑的错误。
    • "line 实际上并没有调用构造函数" -1;强制转换是“调用 ctor”的一种方式“(用户定义的类型 T)没有来自(类型 U)的强制转换””没有像 UDT 这样的东西有来自其他类型的强制转换
    • "这会将指针传递给 Foundation 的构造函数" 请提供一个示例(可编译代码),其中一个参数在 ctor 初始化列表中是可接受的,但在与被cted成员相同的类型
    猜你喜欢
    • 2023-03-24
    • 2018-12-02
    • 1970-01-01
    • 2012-07-22
    • 2011-02-14
    • 1970-01-01
    • 2014-11-09
    • 2019-05-10
    • 1970-01-01
    相关资源
    最近更新 更多