1

I'm working on a swift project which incorporates a C++ library (bullet physics). Currently I achieve this by wrapping the C++ library with Objective-C, and then using the Objectve-C Code in Swift via bridging header.

I would like to eliminate the Objective-C wrapper, and access Bullet through a pure C interface in the interest of making the code more platform agnostic.

Conceptually, I understand how to create a C interface for C++ code by using extern "C", but I don't know how to make the types from the C++ library available in my Swift Code.

For instance, I would like to be able to do something like this:

// MyPhysicsObject.swift

class MyPhysicsObject {

    let rigidBody: btRigidBody

    init() {
        self.rigidBody = createRigidBody()  //called from C interface
    }

}

With a C header file:

// BulletCInterface.h

#ifdef __cplusplus
extern "C" {
#endif

btRigidBody* createRigidBody();

#ifdef __cplusplus
}
#endif

And a C++ implementation file:

//BulletCInterface.cpp

#import <BulletDynamics/btBulletCollisionCommon.h>
#import <BulletDynamics/btBulletDynamicsCommon.h>

#ifdef __cplusplus
extern "C" {
#endif

btRigidBody* createRigidBody() {
   //invoke the C++ bullet API to produce a btRigid body
   //...
}

#ifdef __cplusplus
}
#endif

But when I attempt this, the compiler complains that btRigidBody is an undefined type in BulletCInterface.h. At a minimum I would like to be able to hold references to these objects in swift, and at best I would like to be able to access their data members (like mass etc.)

How can I expose these C++ types to my Swift code? Or do I have to just make everything a void* and keep track of types myself?

1 Answer 1

1

As stated in Swift documentation, "You cannot import C++ code directly into Swift. Instead, create an Objective-C or C wrapper for C++ code." See https://developer.apple.com/library/content/documentation/Swift/Conceptual/BuildingCocoaApps/.

If you want to keep Objective-C out of the picture, then you need a C wrapper, which is what you are trying to do. You need to wrap C++ types in the C interface callable from Swift. The error about btRigidBody is due to the type not being wrapped. I'm assuming it is a C++ type and its definition is unavailable in the C interface header. If you include a header that defines that type in BulletCInterface.h, that won't work because then it won't be usable in Swift via a bridging header.

The wrapper C interface could have functions that map to methods and data members of the C++ classes you use.

BTW, you don't need #ifdef __cplusplus in BulletCInterface.cpp, just do

// This should return a C wrapper for the btRigidBody C++ type
extern "C" btRigidBodyWrapper* createRigidBody() {
    ...
}

It's all C++ code, so you can use extern "C" without the pre-processor conditionals.

Hopefully this is helpful.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.