C++ Nvidia PhysX 无法将 PxFoundation 转换为 shared_ptr<>
C++ Nvidia PhysX cannot convert PxFoundation to shared_ptr<>
我正在尝试创建一个 PxFoundation 并将其保存在我的成员变量 "foundation" 中,它是一个 std::shared_ptr。但是在创建对象时我得到了这个:
C2440: '<function-style-cast>': cannot convert from 'physx::PxFoundation *' to 'std::shared_ptr<physx::PxFoundation>'
如何将 PxCreateFoundation 函数的原始指针放入 shared_ptr?因为我没有调用任何 PhysX 的构造函数 class 我不能使用 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 studio17\community\vc\tools\msvc.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 studio17\community\vc\tools\msvc.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 studio17\community\vc\tools\msvc.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 class:
/**
\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;
}
//...
}
您的 foundation =
行实际上并未调用构造函数。它试图使用称为 "functional cast" 或 "function-style cast" (#2 here) 的语法将原始指针转换为 shared_ptr
,然后将结果分配给 foundation
变量(已经是 default-constructed)。那是行不通的,因为 shared_ptr
没有从原始指针进行转换(以防止它意外获得它不应该拥有的东西的所有权)。
解决此问题的最佳方法是使用构造函数的初始化列表实际初始化 foundation
指针:
PhysicsEngine::PhysicsEngine() :
foundation(PxCreateFoundation(PX_FOUNDATION_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback))
{
// empty
}
这将指针传递给 foundation
的构造函数,而不是让 foundation
成为 default-constructed 然后在构造函数主体中分配给它。但是如果由于某种原因你真的需要通过赋值来完成,你可以使用 reset
函数来告诉 foundation
获得指针的所有权:
PhysicsEngine::PhysicsEngine()
{
foundation.reset(PxCreateFoundation(PX_FOUNDATION_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback));
}
我好像发现了错误:
PhysX SDK 中的大多数析构函数不是 public。因此,尝试使用其中之一 类 创建智能指针会导致错误。
除了使用原始指针之外,唯一的其他选择是创建自定义删除器:
auto foundation = std::shared_ptr<physx::PxFoundation>(PxCreateFoundation(PX_FOUNDATION_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback), [=](physx::PxFoundation* f)
{
f->release();
});
我正在尝试创建一个 PxFoundation 并将其保存在我的成员变量 "foundation" 中,它是一个 std::shared_ptr。但是在创建对象时我得到了这个:
C2440: '<function-style-cast>': cannot convert from 'physx::PxFoundation *' to 'std::shared_ptr<physx::PxFoundation>'
如何将 PxCreateFoundation 函数的原始指针放入 shared_ptr?因为我没有调用任何 PhysX 的构造函数 class 我不能使用 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 studio17\community\vc\tools\msvc.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 studio17\community\vc\tools\msvc.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 studio17\community\vc\tools\msvc.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 class:
/**
\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;
}
//...
}
您的 foundation =
行实际上并未调用构造函数。它试图使用称为 "functional cast" 或 "function-style cast" (#2 here) 的语法将原始指针转换为 shared_ptr
,然后将结果分配给 foundation
变量(已经是 default-constructed)。那是行不通的,因为 shared_ptr
没有从原始指针进行转换(以防止它意外获得它不应该拥有的东西的所有权)。
解决此问题的最佳方法是使用构造函数的初始化列表实际初始化 foundation
指针:
PhysicsEngine::PhysicsEngine() :
foundation(PxCreateFoundation(PX_FOUNDATION_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback))
{
// empty
}
这将指针传递给 foundation
的构造函数,而不是让 foundation
成为 default-constructed 然后在构造函数主体中分配给它。但是如果由于某种原因你真的需要通过赋值来完成,你可以使用 reset
函数来告诉 foundation
获得指针的所有权:
PhysicsEngine::PhysicsEngine()
{
foundation.reset(PxCreateFoundation(PX_FOUNDATION_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback));
}
我好像发现了错误: PhysX SDK 中的大多数析构函数不是 public。因此,尝试使用其中之一 类 创建智能指针会导致错误。 除了使用原始指针之外,唯一的其他选择是创建自定义删除器:
auto foundation = std::shared_ptr<physx::PxFoundation>(PxCreateFoundation(PX_FOUNDATION_VERSION, gDefaultAllocatorCallback, gDefaultErrorCallback), [=](physx::PxFoundation* f)
{
f->release();
});