仅在库 cpp 中具有定义的 forward-declare 结构

Forward-declare struct which only has definition in a library cpp

提问人:Silverlan 提问时间:8/11/2015 更新时间:8/11/2015 访问量:213

问:

我正在使用bullet 3物理库,该库在其中一个cpp中具有以下结构定义:

struct btSingleContactCallback : public btBroadphaseAabbCallback
{

    btCollisionObject* m_collisionObject;
    btCollisionWorld*   m_world;
    btCollisionWorld::ContactResultCallback&    m_resultCallback;


    btSingleContactCallback(btCollisionObject* collisionObject, btCollisionWorld* world,btCollisionWorld::ContactResultCallback& resultCallback)
        :m_collisionObject(collisionObject),
        m_world(world),
        m_resultCallback(resultCallback)
    {
    }

    virtual bool    process(const btBroadphaseProxy* proxy)
    {
        btCollisionObject*  collisionObject = (btCollisionObject*)proxy->m_clientObject;
        if (collisionObject == m_collisionObject)
            return true;

        //only perform raycast if filterMask matches
            if(m_resultCallback.needsCollision(collisionObject->getBroadphaseHandle())) 
        {
            btCollisionObjectWrapper ob0(0,m_collisionObject->getCollisionShape(),m_collisionObject,m_collisionObject->getWorldTransform(),-1,-1);
            btCollisionObjectWrapper ob1(0,collisionObject->getCollisionShape(),collisionObject,collisionObject->getWorldTransform(),-1,-1);

            btCollisionAlgorithm* algorithm = m_world->getDispatcher()->findAlgorithm(&ob0,&ob1);
            if (algorithm)
            {
                btBridgedManifoldResult contactPointResult(&ob0,&ob1, m_resultCallback);
                //discrete collision detection query

                algorithm->processCollision(&ob0,&ob1, m_world->getDispatchInfo(),&contactPointResult);

                algorithm->~btCollisionAlgorithm();
                m_world->getDispatcher()->freeCollisionAlgorithm(algorithm);
            }
        }
        return true;
    }
};

问题是,结构从未在任何标头中声明,但是我需要能够创建这种类型的对象。项目符号库是静态链接的,所以我想我应该能够在我的主程序中自己声明它:

struct btSingleContactCallback
    : public btBroadphaseAabbCallback
{
    btCollisionObject *m_collisionObject;
    btCollisionWorld *m_world;
    btCollisionWorld::ContactResultCallback &m_resultCallback;
    btSingleContactCallback(btCollisionObject *collisionObject,btCollisionWorld *world,btCollisionWorld::ContactResultCallback &resultCallback);
    virtual bool process(const btBroadphaseProxy *proxy);
};

只要我在调试模式下编译,这实际上就可以正常工作。但是,当尝试在发布模式下编译时,我收到一个未解决的符号错误:

physenvironment.obj : error LNK2001: unresolved external symbol "public: __cdecl btSingleContactCallback::btSingleContactCallback(class btCollisionObject *,class btCollisionWorld *,struct btCollisionWorld::ContactResultCallback &)" (??0btSingleContactCallback@@QEAA@PEAVbtCollisionObject@@PEAVbtCollisionWorld@@AEAUContactResultCallback@2@@Z)

这可能与 c++ 的名称篡改有关吗?有没有办法避免它,而不必开始对库本身进行修改?

c++ 结构 static-libraries forward-declaration unresolved-external

评论

0赞 m.s. 8/11/2015
为什么不将此结构的实现复制到代码中呢?
4赞 Mark B 8/11/2015
您能否详细说明一下您尝试使用库的私有实现细节来解决的问题?
0赞 Caninonos 8/11/2015
我第二个马克B。您确定应该实例化该类吗?我的意思是,通常,库带有包含转发声明的标头。如果你真的应该使用这个类,那么你应该通知库的作者,以便他们在标题中包含声明(但这将是令人惊讶的)。
0赞 Silverlan 8/11/2015
我相信这是库中的一个疏忽,但是有一个公共函数将这种类型的结构作为参数之一,并且对于我需要做的事情别无选择。

答:

-1赞 Mark Jansen 8/11/2015 #1

您没有实现构造函数。

评论

0赞 Silverlan 8/11/2015
好吧,不,构造函数已经在库中实现。
1赞 Mark Jansen 8/11/2015
类也是如此,但你也不能使用它。链接器已确定您不能(因此也不应)在其翻译单元之外使用该函数,并且未在发布 .lib 中包含该符号
2赞 Mark B 8/11/2015 #2

从五分钟的库代码来看,你实际上应该使用哪个是公共的,让实现为你创建和使用私有的。ContactResultCallbackbtCollisionWorld::contactTestbtSingleContactCallback

评论

0赞 Silverlan 8/11/2015
没错,但是我需要访问 btBroadphaseInterface::aabbTest ,这也是一个公共函数,但只接受 btSingleContactCallback 类型的对象。aabbTest 允许我指定一个形状,而 contactTest 则不这样做。
0赞 Mark B 8/11/2015
据我所知,接受回调。btBroadphaseInterface::aabbTestbtBroadphaseAabbCallback
0赞 Silverlan 8/12/2015
btSingleContactCallback 派生自 btBroadphaseAabbCallback。我可以编写自己的类,该类派生自 btBroadphaseAabbCallback,但是 btSingleContactCallback 已经完全符合我的要求,并且我想避免复制粘贴它。