代码之家  ›  专栏  ›  技术社区  ›  Kevin Kuegler

C++Nvidia PhysX无法将PxFoundation转换为shared\u ptr

  •  0
  • Kevin Kuegler  · 技术社区  · 6 年前

    我正在尝试创建一个PxFoundation并将其保存在我的成员变量“foundation”中,它是一个std::shared\u ptr。然而,在创建对象时,我得到了以下结果:

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

    如何将PxCreateFoundation函数中的原始指针放入shared\u ptr?由于我没有调用任何PhysX类的ctor,所以我不能使用std::make\u shared,所以使用普通的std::shared\u 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
    

    编辑2:

    以下是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);
    }
    

    PX基础等级:

    /**
    \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;
        }
    //...
    }
    
    2 回复  |  直到 6 年前
        1
  •  2
  •   Kevin Kuegler    6 年前

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

    auto foundation = std::shared_ptr<physx::PxFoundation>(PxCreateFoundation(PX_FOUNDATION_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback), [=](physx::PxFoundation* f)
    {
        f->release();
    });
    
        2
  •  -1
  •   Wyzard    6 年前

    你的 foundation = line实际上并没有调用构造函数。它试图将原始指针投射到 shared_ptr 使用称为“函数类型转换”或“函数样式转换”的语法(#2 here ),然后将结果分配给 foundation 变量(已默认构造)。这行不通,因为 共享\u ptr 没有原始指针的强制转换(以防止它意外获得不应该拥有的东西的所有权)。

    解决此问题的最佳方法是使用构造函数的初始值设定项列表来实际初始化 地基 使用指针:

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

    这会将指针传递到 地基 的构造函数,而不是 地基 是默认构造的,然后在构造函数体中分配给它。但如果出于某种原因确实需要通过分配来完成,可以使用 reset 要告知的功能 地基 要获取指针的所有权,请执行以下操作:

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