Écrire des méthodes Ruby en utilisant C (Partie 1)

table des matières

Ecrire des méthodes Ruby en utilisant C (Partie 1) <-Here Écrire des méthodes Ruby en utilisant C (Partie 2) Numo :: NArray

introduction

Reportez-vous à "Ecrire des méthodes Ruby en C ++ (Partie 1)" pour savoir comment écrire une bibliothèque d'extension Ruby en C ++. .. Si vous écrivez C ++, vous pouvez créer une bibliothèque presque sans effort, donc si vous l'écrivez à partir de zéro, je le recommande.

Ici, nous allons vous montrer comment transformer une fonction écrite en C en une bibliothèque d'extensions. Vous pouvez écrire en C ++ de la même manière qu'en C, vous pouvez donc l'utiliser même si vous avez déjà une bibliothèque écrite en C.

    1. vous montrera comment passer à des variables simples telles que double, float, int, 3. passer à une chaîne et 4. transformer une bibliothèque existante en une bibliothèque étendue. Veuillez vous référer à (2) pour savoir comment passer un tableau.

1. Appelez une fonction fournie par le compilateur

Écrivez un fichier de définition d'interface SWIG. Dans% {..%} ci-dessus, lisez le fichier d'en-tête ou écrivez l'équivalent du fichier d'en-tête.

test.i


%module test  //Nom du module La première lettre est convertie en majuscule
%{
#include <math.h>
%}

%include "typemaps.i"
extern double floor(double x);
// double modf(double value, double *iptr);Lors de la réception d'une valeur avec un pointeur*Changer pour OUTPUT
extern double modf(double value, double *OUTPUT);

En bas, j'écris une fonction à appeler depuis Ruby. Il existe de nombreux en-têtes de fonctions dans math.h, mais nous rendrons floor et modf disponibles à partir de Ruby. Le deuxième argument de modf est un pointeur et renvoie une valeur de type double. L'entrée, la sortie et l'entrée / sortie sont possibles avec le pointeur, et chaque fonction peut être donnée en écrivant * INPUT, * OUTPUT, * INOUT.

extconf.rb


require 'mkmf'
create_makefile("test") #Identique au nom du module

Un programme Ruby pour créer Makefike.

Placez les fichiers ci-dessus dans le même dossier et exécutez la commande suivante.

swig -ruby test.i
ruby extconf.rb
make

Ceci termine test.bundle (l'extension dépend du système d'exploitation). Ceci est un programme de test.

test1.rb


require "./test"
p Test.floor(2.3)
p Test. modf(2.3)

2. Appelez votre propre fonction

J'ai écrit une fonction qui passe une simple variable. C'est juste une fonction C normale. Une fonction qui renvoie deux fois la valeur. Je n'utilise pas de pointeurs.

test2.c


double twicefold_d(double x){
  return(x*2.0);
}

test.i


%module test
%{
double twicefold_d(double x);
%}

double twicefold_d(double x);

Je n'ai pas créé de fichier d'en-tête, alors écrivez l'équivalent du fichier d'en-tête dans% {..%}. Utilisez le même fichier extconf.rb et les mêmes commandes que ci-dessus. S'il y a des fichiers programme tels que .c et .cpp dans le dossier, nous essaierons de tous les compiler et de les lier, alors faites attention à ne pas inclure de fichiers inutiles.

Ceci est un programme de test.

test2.rb


require "./test"
p Test.twicefold_d(3.4)

3. Passez une chaîne qui appelle votre propre fonction

Les chaînes peuvent également être facilement transmises à la fonction.

test3.c


#include "test3.h"
int string_length(char* str){
  return(strlen(str));
}

test3.h


#include <string.h>
int string_length(char* str);

Ici, nous créons un fichier d'en-tête. Cela ne prend pas beaucoup de temps, donc je pense qu'il est plus pratique de créer un fichier d'en-tête.

test.i


%module test
%{
#include "test3.h"
%}

%include test3.h

De même, utilisez le même fichier extconf.rb et les mêmes commandes que ci-dessus.

test1.rb


require "./test"
p Test.string_length("abcd")

4. Rendre les bibliothèques existantes disponibles

Active les fonctions GSL gsl_hypot et gsl_hypot3. Il lit le fichier d'en-tête GSL et définit l'interface entre les deux fonctions. Les deux fonctions sont simplement copiées à partir du fichier d'en-tête et n'ont pas changé.

test.i


%module test
%{
#include "gsl/gsl_math.h"
%}

extern double gsl_hypot(const double x, const double y);
extern double gsl_hypot3(const double x, const double y, const double z);

extconf.rb


require 'mkmf'
dir_config("gsl")
have_header("gsl/gsl_math.h")
have_library("gsl") # libgsl.lien donc
create_makefile("test")

J'ai besoin de lier la lecture du fichier d'en-tête GSL et libgsl.so, j'ai donc ajouté trois lignes pour cela. La commande est souvent la même que ci-dessus, mais si vous ne connaissez pas l'emplacement du fichier d'en-tête et de libgsl.so, écrivez le chemin plus tard dans ruby extconf.rb comme suit:

ruby extconf.rb -- --with-gsl-dir=/path
--with-gsl-include=/path/include
--with-gsl-lib=/path/lib

Lorsque les fichiers se trouvent à des emplacements tels que /path/include/gsl/gsl_math.h et /path/lib/libgsl.so Vous pouvez spécifier les deux à la fois avec --with-gsl-dir = / path. Les deux derniers peuvent être spécifiés un par un.

test4.rb


require "./test"
p Test.gsl_hypot(3, 4)
p Test.gsl_hypot3(3, 4, 5)

CentOS 8.2 / Ruby 2.6.6 / Swig 3.0.12 macOS 10.13.6 / Ruby 2.7.1 / Swig 4.0.2

Recommended Posts

Écrire des méthodes Ruby en utilisant C (Partie 1)
Écrire des méthodes Ruby à l'aide de C ++ (Partie 2) Benchmark
Écrire des méthodes Ruby en utilisant C (Numo :: NArray)
Écrire du code à l'aide de classes et d'instances Ruby
À propos des méthodes Ruby
Essayez d'utiliser la méthode java.lang.Math
Essayez d'utiliser Talend Part 2
À propos des méthodes d'instance Ruby
Essayez d'utiliser Talend Part 1
Méthode [Ruby], méthode d'instance ...
J'ai écrit un analyseur C (comme) en utilisant PEG dans Ruby
Résolution avec Ruby, Perl et Java AtCoder ABC 129 C (Partie 1)
Écrire l'héritage de classe dans Ruby
Essayez d'utiliser Cocoa de Ruby
Programmation DB avec EclipseLink part1
Créer un calendrier avec Ruby
Utiliser le programme C de Ruby
Rubis de type statique avec sorbet
Extension Ruby C et volatile
Créer une loterie avec Ruby
Que sont les méthodes de classe Ruby?
[Ruby] Méthodes singulières et classes singulières
[Ruby] Méthodes de classe, méthodes d'instance, etc.
Élément 88: Écriture défensive des méthodes readObject
Méthodes et classes Ruby (basiques)
[Programmation complète] §2 Essayez d'utiliser Ruby
Comment écrire un exemple d'implémentation F03 ruby et C en temps réel hors ligne