Using C++ libraries in Swift projects?


(Ethin Probst) #1

Hello all,
I was wondering how I could go about using the Boost library project
(among others) in swift? For instance, how would I write the following
program in swift?
#include <boost/log/trivial.hpp>

int main(int, char*[])
{
    BOOST_LOG_TRIVIAL(trace) << "A trace severity message";
    BOOST_LOG_TRIVIAL(debug) << "A debug severity message";
    BOOST_LOG_TRIVIAL(info) << "An informational severity message";
    BOOST_LOG_TRIVIAL(warning) << "A warning severity message";
    BOOST_LOG_TRIVIAL(error) << "An error severity message";
    BOOST_LOG_TRIVIAL(fatal) << "A fatal severity message";

    return 0;
}
Yes, I copied this program from
http://www.boost.org/doc/libs/1_63_0/libs/log/doc/html/log/tutorial.html.
But I want to know how to do this so I can play around with it.

···

--
Signed,
Ethin D. Probst


(Jens Alfke) #2

No, it’s generally not feasible to use C++ libraries from any other language. The main reasons are that (a) name-mangling of C++ functions means that there’s no reliable way to tell the other language the name of the function you want to call, and (b) C++ has so many language features that are tightly entwined with the way you call functions — constructors, copying, assignment, references, implicit conversions, operator overloading, etc.

In the simple example you gave there are several warning signs:
* BOOST_LOG_TRIVIAL etc. appear to be macros since they’re in all caps. Who knows what functions they actually call?
* The “<<“ operator expands [unmangles] to some complex function name which is very compiler-dependent.
* It’s very probable that the “<<“ operator is defined as an inline function, so it may not even appear in the binary of the compiled Boost library at all.
* The C string constants on the right hand side are probably being implicitly converted to C++ std::strings before the call. Or maybe not. And the conversion likely happens on the caller’s side, i.e. the compiler has to know to create a std::string before calling and then destruct it afterwards.

The only practical way to call a C++ API from another language is to write glue code, a set of functions that call the library, but which have a plain C API and use only C types. Pretty much any language has a way to call C functions, so you can now call the C API which will call the C++ code.

—Jens

···

On Jan 13, 2017, at 8:18 AM, Ethin Probst via swift-users <swift-users@swift.org> wrote:

I was wondering how I could go about using the Boost library project
(among others) in swift?


(Ethin Probst) #3

So you don't know how I could directly port this to Swift--or make an
indirect port?

···

On 1/13/17, Jens Alfke <jens@mooseyard.com> wrote:

On Jan 13, 2017, at 8:18 AM, Ethin Probst via swift-users >> <swift-users@swift.org> wrote:

I was wondering how I could go about using the Boost library project
(among others) in swift?

No, it’s generally not feasible to use C++ libraries from any other
language. The main reasons are that (a) name-mangling of C++ functions means
that there’s no reliable way to tell the other language the name of the
function you want to call, and (b) C++ has so many language features that
are tightly entwined with the way you call functions — constructors,
copying, assignment, references, implicit conversions, operator overloading,
etc.

In the simple example you gave there are several warning signs:
* BOOST_LOG_TRIVIAL etc. appear to be macros since they’re in all caps. Who
knows what functions they actually call?
* The “<<“ operator expands [unmangles] to some complex function name which
is very compiler-dependent.
* It’s very probable that the “<<“ operator is defined as an inline
function, so it may not even appear in the binary of the compiled Boost
library at all.
* The C string constants on the right hand side are probably being
implicitly converted to C++ std::strings before the call. Or maybe not. And
the conversion likely happens on the caller’s side, i.e. the compiler has to
know to create a std::string before calling and then destruct it
afterwards.

The only practical way to call a C++ API from another language is to write
glue code, a set of functions that call the library, but which have a plain
C API and use only C types. Pretty much any language has a way to call C
functions, so you can now call the C API which will call the C++ code.

—Jens

--
Signed,
Ethin D. Probst


(Jens Alfke) #4

It’s not clear to me what you’re asking. Do you just want to write to a log file from Swift? Or do you want to specifically call into Boost’s logging implementation? Or do you want to reimplement something equivalent to Boost’s logging library in Swift?

—Jens

···

On Jan 13, 2017, at 9:37 AM, Ethin Probst <harlydavidsen@gmail.com> wrote:

So you don't know how I could directly port this to Swift--or make an
indirect port?


(Jonathan Prescott) #5

To take two lines from your example, you could do something like this if you don’t want to re-write Boost.Logging or build/use native Swift facilities to write to logs:

BoostLog.h: // Use this to bridge to Swift via C-compatibility

extern “C” void logTrace(const char * str);
extern “C” void logDebug(const char * str);

BoostLog.cpp: // this is the implementation

#include “BoostLog.h”
#include <boost/log/trivial.hpp>
#include <string>

void logTrace(const char* str)
{
  BOOST_LOG_TRIVIAL(trace) << std::string(str);
}

void logDebug(const char* str)
{
  BOOST_LOG_TRIVIAL(debug) << std::string(str);
}

You would then use logTrace and logDebug within Swift like any other C-functions(using the appropriate Swift<->C interoperability conventions). How you package it up to include in your Swift project is another whole subject.

This is the general scheme by which you would include C++ into Swift (or any other language other than Obj-C++, for that matter, as Jens as noted previously).

Jonathan

···

On Jan 13, 2017, at 12:37 PM, Ethin Probst via swift-users <swift-users@swift.org> wrote:

So you don't know how I could directly port this to Swift--or make an
indirect port?

On 1/13/17, Jens Alfke <jens@mooseyard.com <mailto:jens@mooseyard.com>> wrote:

On Jan 13, 2017, at 8:18 AM, Ethin Probst via swift-users >>> <swift-users@swift.org> wrote

I was wondering how I could go about using the Boost library project
(among others) in swift?

No, it’s generally not feasible to use C++ libraries from any other
language. The main reasons are that (a) name-mangling of C++ functions means
that there’s no reliable way to tell the other language the name of the
function you want to call, and (b) C++ has so many language features that
are tightly entwined with the way you call functions — constructors,
copying, assignment, references, implicit conversions, operator overloading,
etc.

In the simple example you gave there are several warning signs:
* BOOST_LOG_TRIVIAL etc. appear to be macros since they’re in all caps. Who
knows what functions they actually call?
* The “<<“ operator expands [unmangles] to some complex function name which
is very compiler-dependent.
* It’s very probable that the “<<“ operator is defined as an inline
function, so it may not even appear in the binary of the compiled Boost
library at all.
* The C string constants on the right hand side are probably being
implicitly converted to C++ std::strings before the call. Or maybe not. And
the conversion likely happens on the caller’s side, i.e. the compiler has to
know to create a std::string before calling and then destruct it
afterwards.

The only practical way to call a C++ API from another language is to write
glue code, a set of functions that call the library, but which have a plain
C API and use only C types. Pretty much any language has a way to call C
functions, so you can now call the C API which will call the C++ code.

—Jens

--
Signed,
Ethin D. Probst
_______________________________________________
swift-users mailing list
swift-users@swift.org <mailto:swift-users@swift.org>
https://lists.swift.org/mailman/listinfo/swift-users