2017-01-17 2 views
2

Angenommen ich einen C-Code haben (dcomplex.h):Wie verwenden Sie eine feste Größe C-Array-Typ in Vala?

typedef double dcomplex[2]; 

und wollen einen solchen Datentyp in Vala verwenden. Was kann die minimale VAPI-Datei und Vala Anruf dafür sein?

(Das ultimative Ziel ist es, die C99 complex.h Typen zu verwenden.)

ich viele Varianten der folgenden dcomplex.vapi Datei versucht:

[CCode (cheader_filename = "dcomplex.h")] 
namespace DComplex { 
    [SimpleType] 
    [CCode (cname = "dcomplex", has_type_id = false)] 
    public struct DoubleComplex { 
    } 
} 

und Verwendung in vala Code wie:

using DComplex; 
void main() 
{ 
    DoubleComplex x = {1.0, 2.0}; 
    stdout.printf("x = %f + i %f\n", x[0], x[1]); 
} 

Die Compilation

valac --vapidir . --pkg dcomplex test.vala 

führt zu Fehlern:

error: too many expressions in initializer list for `Complex.DoubleComplex' 
DoubleComplex x = {1.0, 2.0}; 
        ^^^ 

error: The expression `Complex.DoubleComplex' does not denote an array 
stdout.printf("x = %f + i %f\n", x[0], x[1]); 
           ^^^^ 
+0

DoubleComplex x = {1,0, 2,0}; - kann dieser Typ sein: "DoubleComplex" ist eine Struktur, nicht ein Array von 2 Elementen? –

+0

Das ist natürlich die richtige Beobachtung. Ein solches Verhalten ist etwas zu erwarten. Die Frage ist, was zu verwenden ist, damit es irgendwie funktioniert. Der vala vapi doc sagt zum Beispiel auch 'public struct Sth: double {}'. Aber ich kann es nicht für Arrays wie 'public struct DoubleComplex: double [2] {}' verwenden. –

Antwort

2
  1. public struct DoubleComplex: Ich glaube nicht, Sie zu einem typedefed C-Array binden können und erwarten Vala der Lage sein, ihre Mitglieder oder Felder zuzugreifen.

  2. DoubleComplex x = {1.0, 2.0}; ist eine Initialisierung von Arrays. Sie können diese Initialisierung nicht verwenden, da wir Vala nicht wissen lassen können, dass es sich bei dem Typ um ein binded "opaque" -Array handelt.

Ich verstehe Sie C99 komplexe Funktionen nutzen möchten, so, brüllen, präsentiere ich meine Lösung complex.h zu binden. Um den komplexen Header Vala fieser zu machen, würde ich nicht schreiben und VAPI, um ihn direkt zu binden, stattdessen würde ich einen C-Wrapper-Objekt-basierten Stil schreiben, der double complex an etwas bindet, an das Vala binden kann.

Zuerst habe ich den Wrapper zeigen werde, wird es aus drei Dateien zusammen:

  • Complex.h für den Prototypen, typedef und Einbeziehung von <complex.h>;
  • Complex.c für die Implementierung von Wrapper-Funktionen und;
  • Complex.vapi in Vala zu binden.

Datei Complex.h

#include <complex.h> 

typedef double complex dcomplex; 

void dcomplex_make (dcomplex * c, double r, double i); 

double dcomplex_real (dcomplex * c); 
double dcomplex_imag (dcomplex * c); 

Datei Complex.c

#include "Complex.h" 

void dcomplex_make (dcomplex * c, double r, double i) 
{ 
    *c = CMPLX(r, i); 
} 

double dcomplex_real (dcomplex * c) 
{ 
    return creal(*c); 
} 

double dcomplex_imag (dcomplex * c) 
{ 
    return cimag(*c); 
} 

Datei Complex.vapi

[CCode (cheader_filename = "Complex.h")] 
namespace Complex 
{ 
    [CCode (cname = "dcomplex")] 
    public struct DComplex { 
     [CCode (cname = "dcomplex_make")] 
     public DComplex (double real, double imaginary); 

     [CCode (cname = "dcomplex_real")] 
     public double real(); 

     [CCode (cname = "dcomplex_imag")] 
     public double imag(); 
    } 
} 

Jetzt, wo Sie den Wrapper haben und VAPI, können Sie es in Vala Code verwenden:

Datei Main.vala

using Complex; 

class Main { 
    static void main() { 
     DComplex c = DComplex(10, 20); 

     stdout.printf("C Complex Type = %f %f\n", c.real(), c.imag()); 
    } 
} 

Aufbau und Betrieb:

# valac Main.vala Complex.vapi Complex.c 
# ./Main 

dargestellten Beispiel Ausgänge:

C Complex Type = 10.000000 20.000000 
+0

Das ist eine sehr schön codierte Antwort, danke! –

Verwandte Themen