website/programming/bridging.md

211 lines
4.4 KiB
Markdown
Raw Permalink Normal View History

2025-08-03 16:27:25 +02:00
---
layout: default
title: Bridging between languages
categories: programming
---
We can cross call functions from languages that:
- Both are compilable → Strategy: Create a binary library and call function from it.
- Library in `interpreted` and the project in `compiled` → Strategy: Create an interpreter context, then load the files and execute them.
- Library in `compiled` and the project in `interpreted` → Strategy: Use `FFI`.
- Both are interpreted
- Probably give up. Bridging will be possible, but messy and complicated
- Create two programs and exchange data between them using pipe, sockets, message quesues, databses etc.
### Creating shared and static library in Go
An example code that is shared [`example.go`](https://github.com/artur-gurgul/codebook):
``` go
package main
import "C"
import "fmt"
//export SayHello
func SayHello(hello *C.char) {
fmt.Print(C.GoString(hello))
}
func main() {}
```
- The `main` function is neccecery to include into library, because the final product has to have for example the GC rutines.
- The comment starting from `//export {function name}` tells the comiler that this the function will be called from the outside.
#### Creating static library
```
go build -o example.a -buildmode=c-archive example.go
```
#### Creating dynamic library
```
go build -o example.dylib -buildmode=c-shared example.go
```
### Creating shared and static library in Swift
`point.swift`
```swift point.swift
public struct Point {
public let x: Int
public let y: Int
public init(x: Int, y: Int) {
self.x = x
self.y = y
}
}
```
and compile with command (module name is optional)
```sh
swiftc point.swift -emit-module  -module-name Point -emit-library -static
```
**Using**
```swift
import Point
let p = Point(x: 4, y: 20)
print("Hello library!", p.x, p.y)
```
compile with
```sh
swiftc main.swift -L ./lib/ -I ./lib/ -lpoint
```
#### Dynamic library in Swift
```
swiftc point.swift -emit-module -emit-library
```
it produces
- `libpoint.a`
- `point.swiftdoc`
- `point.swiftmodule`
- `point.swiftsourceinfo`
Compile main program the same way as it has been down with the static one
Library searching paths `/usr/lib/`, `/usr/local/lib/` 
**_Create package that emits library_**
```swift
// swift-tools-version:5.3
import PackageDescription
let package = Package(
name: "MyLibrary",
products: [
/// type: automatic, based on the environment
.library(name: "MyLibrary",
// type: .dynamic, .static
targets: ["MyLibrary"]
),
],
targets: [
.target(name: "MyLibrary", dependencies: []),
]
)
```
### Calling function from library in Go
First off we will create C++ library that we will use in out Go program.
File `example.cxx`:
```c++
#include <stdio.h>
extern "C" {
void PrintHello(const char* u) {
printf("Hello: %s\n", u);
}
}
```
And `example.hxx`:
```c++
#pragma once
void PrintHello(const char* u)
```
`extern "C" {}` informs the compiler that we want the function names to be preserved. That is, to not "mangle" the names as is done for C++ code:
#### Creating static library
```bash
clang++ -c -Wall -o lib.o ./example.cxx
ar rc ./libexample.a ./lib.o
```
#### Creating dynamic library
```bash
clang++ -dynamiclib -o libexample.dylib example.cxx
```
## Statically linking an example library in Go
```go
package main
// #cgo CFLAGS: -I.
// #cgo LDFLAGS: -L. -lexample
//
// #include <example.hxx>
import "C"
func main() {
C.PrintHello(C.CString("Hello Golang"))
}
```
The program is linked staticaly with libexample when you build it.
#### Example of using library with FFI in Ruby
```shell
gem install ffi
```
```ruby
require 'ffi'
module Example
extend FFI::Library
ffi_lib './example.dylib'
attach_function :SayHello, [:string]
end
```
```ruby
Example.SayHello("Hello")
```
More informations about FFI: [https://en.wikipedia.org/wiki/Foreign_function_interface](https://en.wikipedia.org/wiki/Foreign_function_interface)
#### Call shared library from Python
```python
import ctypes
libc = ctypes.CDLL('./example.dylib')
libc.SayHello("Hello")
```
## Interesting websites
- [https://blog.filippo.io/building-python-modules-with-go-1-5/](https://blog.filippo.io/building-python-modules-with-go-1-5/)
- [https://id-rsa.pub/post/go15-calling-go-shared-libs-from-firefox-addon/](https://id-rsa.pub/post/go15-calling-go-shared-libs-from-firefox-addon/)