1

This gist is a simple example on how to call a function written in swift from C/...

 1 year ago
source link: https://gist.github.com/HiImJulien/c79f07a8a619431b88ea33cca51de787
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

Swift Meets C/C++

This gist is a simple example on how to call a function written in swift from C/C++, without taking the detour via Objective-C/C++.


In this example we're going to invoke a function called say_hello, which, as the name already suggests, prints "Hello, World!" to the terminal.

say_hello is defined as following:

// func.swift

@_cdecl("say_hello")
public func say_hello(){
    print("Hello, World!")
}

This is just the canonical "Hello, World!"-example wrapped in a function called say\_hello. The only thing, that stands out, is the attribute @_cdecl("say\_hello").

@_cdecl is an undocumented attribute, which according to vague informations found on the web, enforces C-name mangling. Note: @_cdecl solely enforces the name mangling; not the calling convention!

In order to link our code with a C/C++ application, will need a library. In order to compile our code as a linked library, specify -emit-library when compiling the .swift-file.

We want to link our swift code with our C/C++ applications, which means, that we'll need this code to be compiled as a library. In order to compiler our code as a linked library, just specify '-emit-library' when compiling the .swift-file.

swiftc func.swift -emit-library

This will result in a linked library called "libfunc.dylib" (or "libfunc.so" on Linux, I suppose), which exports our function say_hello as _say_hello.


Now to our C++:

// main.cpp

// only "extern" when targeting C.
extern "C" void say_hello();

int main(){
    say_hello();    // Prints "Hello, World!"
    return 0;
}

Here we declare say_hello as an external reference, which will be provided by the library, we compiled before.

What's left at this point is just to compile and link our code.

gcc -std=c++11 -c main.cpp -o main.o 
gcc libfunc.dylib main.o -o main

When we run the application, we're getting greeted with following:

./main
> Hello, World!

This was my first "technical article". Feedback is welcome!

None the less, I hope I could help you with this "article".

J. Kirsch

Resources

  • SO Answer by Max Desiatov
  • Trial'n'Error with the command line tool nm
  • Other links, that I cannot remember... :-(

About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK