Aujourd’hui, les grandes entreprises et administrations publiques hésitent entre continuer à utiliser des logiciels propriétaires ou basculer vers les Logiciels Libres. Pourtant, la plupart des logiciels libres sont capables de bien traiter les données issues des logiciels propriétaire, et parfois avec une meilleur compatibilité.
C’est alors la barrière de la prise en main qui fait peur, et pourtant...
Les logiciels libres
L’aspect « Logiciel Libre » permet une évolution rapide et une plus grande participation des utilisateurs. Les aides et tutoriels foisonnent sur Internet ou sont directement inclus dans le logiciel lui-même.
Enfin, les concepteurs sont plus proches des utilisateurs, ce qui rend les logiciels libres plus agréable à utiliser et conviviaux.
Grâce à la disponibilité des logiciels libres, vous trouverez facilement des services de support techniques et la licence n’est plus un frein à l’utilisation de ces logiciels par votre personnel.
Notre support technique concerne essentiellement les logiciels libres, que ce soit sous forme de services ponctuels ou de tutoriels.
- Juin 2022 -
Hello :)
Aperçu du projet
Koffi, c'est un petit projet que j'ai démarré un petit peu par hasard il y a 4 mois, après avoir eu besoin d'appeler du C depuis un projet Node.js. J'ai commencé par utiliser node-ffi et node-ffi-napi, mais les performances étaient désastreuses. J'ai essayé d'autres paquets (comme fastcall, basé sur dyncall), mais il leur manque trop de choses : notamment, le passage de structures par valeur (en paramètre ou en valeur de retour) n'est pas implémenté.
J'ai commencé Koffi pour m'amuser, en C++ et en assembleur, sans réutiliser de code existant comme libffi. Tout est from scratch, en suivant la documentation des différentes ABI.
Fonctionnalités
Je sors aujourd'hui la version 1.3.0, qui commence à être assez complète :
- Haute performance : l'overhead est 10 à 100x inférieur à celui de node-ffi et node-ffi-napi, chiffres à l'appui : https://koffi.dev/benchmarks#rand-results
- Support multi-architecture : Windows (x86, x64, ARM64), Linux (x86, x64, ARM32, ARM64, RISC-V 64), macOS (x64, ARM64), et les autres systèmes POSIX comme FreeBSD et OpenBSD.
- Types de valeurs : presque tout y est, sauf les unions pour le moment. Les structures c'est tout bon, qu'elles soient passées par valeur ou par référence (pointeur).
- Support des callbacks : il est possible de passer une fonction Javascript à une fonction C, qui peut l'appeler en callback. Tout ceci fonctionne avec des sauts (trampolines) statiques, donc pas de problème de protection mémoire à prévoir, par exemple sur un noyau PaX.
- Suite de tests assez complète, basée sur QEMU pour tester (ou presque… merci Apple M1) et packager facilement toutes les archi supportées. Ces tests reposent sur tout un tas de fonctions C écrites pour l'occasion (et tester des cas limites), ainsi que des appels à Raylib et à SQLite.
- Support des appels asynchrones.
Et surtout, il y a désormais une documentation assez complète avec pas mal d'exemples en ligne (en anglais) : https://koffi.dev/
Exemple
Le petit exemple ci-dessous, fonctionnel sous Linux, vous illustre comment afficher l'heure actuelle en appelant directement les fonctions de la libc.
const koffi = require('koffi');
// Load the shared library
const lib = koffi.load('libc.so.6');
// Declare struct types
const timeval = koffi.struct('timeval', {
tv_sec: 'unsigned int',
tv_usec: 'unsigned int'
});
const timezone = koffi.struct('timezone', {
tz_minuteswest: 'int',
tz_dsttime: 'int'
});
const time_t = koffi.struct('time_t', { value: 'int64_t' });
const tm = koffi.struct('tm', {
tm_sec: 'int',
tm_min: 'int',
tm_hour: 'int',
tm_mday: 'int',
tm_mon: 'int',
tm_year: 'int',
tm_wday: 'int',
tm_yday: 'int',
tm_isdst: 'int'
});
// Find functions
const gettimeofday = lib.func('int gettimeofday(_Out_ timeval *tv, _Out_ timezone *tz)');
const localtime_r = lib.func('tm *localtime_r(const time_t *timeval, _Out_ tm *result)');
const printf = lib.func('int printf(const char *format, ...)');
// Get local time
let tv = {};
let now = {};
gettimeofday(tv, null);
localtime_r({ value: tv.tv_sec }, now);
// And format it with printf (variadic function)
printf('Hello World!\n');
printf('Local time: %02d:%02d:%02d\n', 'int', now.tm_hour, 'int', now.tm_min, 'int', now.tm_sec);
Pour tester cet exemple, créer un nouveau projet avec npm init
, installez le paquet koffi
puis copiez-coller le code ci-dessus. Ensuite, exécutez-le avec node node time.js
et voilà !
mkdir time
cd time
npm init
npm install koffi
vim time.js # Copier-coller le code JS au-dessus
node time.js
Support
La table ci-dessous résume les combinaisons SE/architecture supportées. Le paquet NPM contient des binaires précompilées pour toutes les combinaisons en vert, donc c'est (en théorie) installable sans avoir besoin de CMake et de compilateur.
ISA / SE |
Windows |
Linux |
macOS |
FreeBSD |
OpenBSD |
x86 (IA32) |
✅ Oui |
✅ Oui |
⬜️ N/A
|
✅ Oui |
✅ Oui |
x86_64 (AMD64) |
✅ Oui |
✅ Oui |
✅ Oui |
✅ Oui |
✅ Oui |
ARM32 LE |
⬜️ N/A
|
✅ Oui |
⬜️ N/A
|
🟨 Probable |
🟨 Probable |
ARM64 (AArch64) LE |
✅ Oui |
✅ Oui |
✅ Oui |
✅ Oui |
🟨 Probable |
RISC-V 64 |
⬜️ N/A
|
✅ Oui |
⬜️ N/A
|
🟨 Probable |
🟨 Probable |
Toutes les architectures supportées le sont complètement, il n'y a pas de demi-mesure. C'est complet ou il n'y a rien. Globalement le projet couvre les plateformes qui sont elles-mêmes supportées par Node.js.
Conclusion
Voilà, si vous avez besoin de faire de la FFI, et/ou que vous avez rencontré des problèmes avec node-ffi/node-ffi-napi, Koffi est là !
Page officielle / documentation : https://koffi.dev/
Paquet NPM : https://www.npmjs.com/package/koffi
Performances : https://koffi.dev/benchmarks#rand-results
Adresse du dépôt (monodépôt) : https://github.com/Koromix/luigi/tree/master/koffi
Si ça vous est utile, ou que ça peut l'être, n'hésitez pas à m'adresser vos retours, bugs et demandes de fonctionnalités :)
Commentaires :
voir le flux Atom
ouvrir dans le navigateur