GitXplorerGitXplorer
a

foreigner

public
26 stars
4 forks
13 issues

Commits

List of commits on branch master.
Verified
96b6bd7b25509e87203a23792d2c1e69a7c4b5fd

Update README

aand3rson committed 3 years ago
Verified
4dc8c2d75db08b71c75822fbee687a7b7befb2fd

Update README.md

aand3rson committed 4 years ago
Verified
324b0bf42adc54c2b3de76374440a5e8cd714b4d

Update README.md

aand3rson committed 4 years ago
Verified
cd1c9aee8c920990c989f103e2ebe6c525f5a414

Merge pull request #6 from follower/patch-2

aand3rson committed 5 years ago
Verified
462d584c1cc925389b3ce12648d054ff4d1412e5

Merge pull request #5 from follower/fix-testlib-path

aand3rson committed 5 years ago
Verified
42dd4ab23417d558ff8c382f5147be6d5360f94c

Merge pull request #4 from follower/patch-1

aand3rson committed 5 years ago

README

The README file for this repository.

Foreigner: a foreign function interface library for Godot 3.1 (WIP)

This repo contains a WIP variant of a FFI adapter for Godot.

IMPORTANT: This project is looking for maintainers!

Please open an issue if you are willing to maintain this library.

Compiling & testing

# Build foreigner.so to use with Godot
make GODOTCPP_PATH=path/to/godot/cpp/sources GODOT_PATH=path/to/godot/sources
# Build testlib.so with some exposed methods
# and run Godot script that loads and tests testlib.so via foreigner API.
make test GODOTCPP_PATH=path/to/godot/cpp/sources GODOT_PATH=path/to/godot/sources

Usage

First of all, download & build godot-cpp according to their instructions.

Then edit the foreigner.gdns file to match the path of your built foreigner.so.

Lastly, use it in Godot as follows:

# Generic example
# See ffi.h of libffi for a list of
# possible argument types.
# One extra type is available - "string".
# It allows passing & returning string `Variant`s
# as char* and const char*.

var foreigner = preload('res://contrib/foreigner/foreigner.gdns').new()
var library = foreigner.open('testlib.so')

library.define('getNumber', 'sint32', [])
print(library.invoke('getNumber'))  # prints 42

library.define('add2i', 'sint32', ['sint32', 'sint32'])
print(library.invoke('add2i', [6, 8]))  # Prints 14

library.define('add3d', 'double', ['double', 'double', 'double'])
print(library.invoke('add3d', [3.0, 4.0, 5.0]))  # Prints 12


# Pointers
# Assuming we have the following shared library functions:
# uint32_t* allocateInt(uint32_t value) { return new int32_t(value) }
# uint32_t retrieveInt(uint32_t *value) { return *value; }

library.define('allocateInt', 'pointer', ['sint32'])
library.define('retrieveInt', 'sint32', ['pointer'])
result = library.invoke('retrieveInt', [library.invoke('allocateInt', [1337])])
print(result)  # Prints 1337


# Strings
library.define('getMessage', 'string', [])
print(library.invoke('getMessage', []))  # Prints Hello world!

library.define('joinStrings', 'string', ['string', 'string'])
print(library.invoke('joinStrings', ['Foo', 'bar']))  # Prints Foobar


# Steam example

var foreigner = preload('res://contrib/foreigner/foreigner.gdns').new()
var library = foreigner.open('libsteam_api.so')

library.define('SteamAPI_Init', 'void', [])
prints(library.invoke('SteamAPI_Init'))

library.define('SteamAPI_IsSteamRunning', 'uchar', [])
prints(library.invoke('SteamAPI_IsSteamRunning'))  # Prints 1

Known limitations

  • Only basic types are currently supported: int, float, strings and pointers.
  • Only Linux is supported right now. This is easy to improve.
  • Memory leaks are possible. This needs some minor attention.
  • Pointer sizes should be added for 8-, 16-, 32-, & 64-bit pointers. Currently uint64_t* is used.

Maintainers