0

I'm using the bullet 3 physics library, which has the following struct definition inside one of the cpps:

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;
    }
};

The problem is, the struct is never declared in any of the headers, I need to be able to create an object of this type however. The bullet libraries are statically linked, so I figured I should just be able to declare it myself in my main program as such:

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);
};

This actually works fine, as long as I'm compiling in debug mode. However, when trying to compile in release mode, I'm getting an unresolved symbol error:

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)

Could this have anything to do with c++'s name mangling? Is there a way to avoid it, without having to start making modifications in the library itself?

Silverlan
  • 2,783
  • 3
  • 31
  • 66
  • why don't you copy the implementation of this struct to your code? – m.s. Aug 11 '15 at 14:02
  • 4
    Can you elaborate on the problem you're trying to solve by using the *private implementation details* of the library? – Mark B Aug 11 '15 at 14:05
  • I second Mark B. Are you sure you are supposed to instantiate that class? I mean, usually, libraries come with headers including forward declarations. If you're really supposed to use that class, then you should notify the library's author(s) so that they include the declaration in a header (but that would be surprising). – Caninonos Aug 11 '15 at 14:07
  • I believe it's an oversight in the library, but there's a _public_ function which takes a struct of this type as one of the parameters, and there's no alternative for what I need to do. – Silverlan Aug 11 '15 at 14:08

2 Answers2

2

From a five minute look at the library code, you actually should use ContactResultCallback which is public, letting the implementation of btCollisionWorld::contactTest create and use the private btSingleContactCallback for you.

Mark B
  • 95,107
  • 10
  • 109
  • 188
  • True, however I need to access _btBroadphaseInterface::aabbTest_ , which is also a public function, but only accepts an object of type _btSingleContactCallback_. _aabbTest_ allows me to specify a shape, which _contactTest_ does not. – Silverlan Aug 11 '15 at 15:53
  • As far as I can see `btBroadphaseInterface::aabbTest` accepts a `btBroadphaseAabbCallback` callback. – Mark B Aug 11 '15 at 15:57
  • _btSingleContactCallback_ is derived from _btBroadphaseAabbCallback_. I could write my own class derived from _btBroadphaseAabbCallback_, however _btSingleContactCallback_ already does exactly what I want and I wanted to avoid having to copy-paste it. – Silverlan Aug 11 '15 at 16:23
-1

You did not implement the constructor.

Mark Jansen
  • 1,491
  • 12
  • 24
  • Well no, the constructor is already implemented in the library. – Silverlan Aug 11 '15 at 14:06
  • 1
    And so is the class, but you cannot use that either. The linker has determined that you cannot (and thus, should not) use the function outside of it's translation unit, and has not included the symbol in the release .lib – Mark Jansen Aug 11 '15 at 14:14