Schreiben Sie Ruby-Methoden mit C (Teil 1) <-Hier Schreiben von Ruby-Methoden mit C (Teil 2) Numo :: NArray
Informationen zum Schreiben von Ruby-Erweiterungsbibliotheken in C ++ finden Sie unter "Schreiben von Ruby-Methoden mit C ++ (Teil 1)". .. Wenn Sie C ++ schreiben, können Sie fast ohne Aufwand eine Bibliothek erstellen. Wenn Sie sie also von Grund auf neu schreiben, empfehle ich dies.
Hier zeigen wir Ihnen, wie Sie eine in C geschriebene Funktion in eine Erweiterungsbibliothek verwandeln. Sie können in C ++ auf die gleiche Weise wie in C schreiben, sodass Sie es auch dann verwenden können, wenn Sie bereits eine Bibliothek in C geschrieben haben.
Schreiben Sie eine SWIG-Schnittstellendefinitionsdatei. Lesen Sie in% {..%} oben die Header-Datei oder schreiben Sie das Äquivalent der Header-Datei.
test.i
%module test //Modulname Der erste Buchstabe wird in Großbuchstaben umgewandelt
%{
#include <math.h>
%}
%include "typemaps.i"
extern double floor(double x);
// double modf(double value, double *iptr);Beim Empfang eines Wertes mit einem Zeiger*Wechseln Sie zu OUTPUT
extern double modf(double value, double *OUTPUT);
Unten schreibe ich eine Funktion, die von Ruby aufgerufen werden soll. Es gibt viele Funktionsüberschriften in math.h, aber wir werden Floor und Modf von Ruby zur Verfügung stellen. Das zweite Argument für modf ist ein Zeiger und gibt einen doppelten Wert zurück. Eingabe, Ausgabe und Eingabe / Ausgabe sind mit dem Zeiger möglich, und jede Funktion kann durch Schreiben von * INPUT, * OUTPUT, * INOUT angegeben werden.
extconf.rb
require 'mkmf'
create_makefile("test") #Entspricht dem Modulnamen
Ein Ruby-Programm zum Erstellen von Makefike.
Legen Sie die obigen Dateien in denselben Ordner und führen Sie den folgenden Befehl aus.
swig -ruby test.i
ruby extconf.rb
make
Damit ist test.bundle abgeschlossen (die Erweiterung hängt vom Betriebssystem ab). Dies ist ein Testprogramm.
test1.rb
require "./test"
p Test.floor(2.3)
p Test. modf(2.3)
Ich habe eine Funktion geschrieben, die eine einfache Variable übergibt. Es ist nur eine normale C-Funktion. Eine Funktion, die den doppelten Wert zurückgibt. Ich benutze keine Zeiger.
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);
Ich habe keine Header-Datei erstellt, schreiben Sie also das Äquivalent der Header-Datei in% {..%}. Verwenden Sie dieselbe extconf.rb-Datei und dieselben Befehle wie oben. Wenn sich Programmdateien wie .c und .cpp im Ordner befinden, werden wir versuchen, sie alle zu kompilieren und zu verknüpfen. Achten Sie daher darauf, keine unnötigen Dateien einzuschließen.
Dies ist ein Testprogramm.
test2.rb
require "./test"
p Test.twicefold_d(3.4)
Strings können auch einfach an die Funktion übergeben werden.
test3.c
#include "test3.h"
int string_length(char* str){
return(strlen(str));
}
test3.h
#include <string.h>
int string_length(char* str);
Hier erstellen wir eine Header-Datei. Es dauert nicht lange, daher ist es meiner Meinung nach bequemer, eine Header-Datei zu erstellen.
test.i
%module test
%{
#include "test3.h"
%}
%include test3.h
Verwenden Sie in ähnlicher Weise dieselbe extconf.rb-Datei und dieselben Befehle wie oben.
test1.rb
require "./test"
p Test.string_length("abcd")
Aktiviert die GSL-Funktionen gsl_hypot und gsl_hypot3. Es liest die GSL-Header-Datei und definiert die Schnittstelle zwischen den beiden Funktionen. Die beiden Funktionen werden nur aus der Header-Datei kopiert und haben sich nicht geändert.
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.Link so
create_makefile("test")
Ich muss das Lesen der GSL-Header-Datei und libgsl.so verknüpfen, daher habe ich drei Zeilen hinzugefügt. Der Befehl ist häufig derselbe wie oben, aber wenn Sie den Speicherort der Header-Datei und von libgsl.so nicht kennen, schreiben Sie den Pfad später in ruby extconf.rb wie folgt:
ruby extconf.rb -- --with-gsl-dir=/path
--with-gsl-include=/path/include
--with-gsl-lib=/path/lib
Wenn sich Dateien an Speicherorten wie /path/include/gsl/gsl_math.h und /path/lib/libgsl.so befinden Sie können beide gleichzeitig mit --with-gsl-dir = / path angeben. Die beiden unteren können einzeln angegeben werden.
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