2017-01-17 5 views
2

Предположим, у меня есть код C (dcomplex.h):Как использовать тип массива с фиксированным размером C в vala?

typedef double dcomplex[2]; 

и хотите использовать такой тип данных в Вала. Каким может быть минимальный файл vapi и вала?

(Конечная цель состоит в том, чтобы использовать типы C99 complex.h.)

Я пробовал много вариантов следующего dcomplex.vapi файла:

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

и используя в Vala коде, как:

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

компиляция

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

приводит к ошибкам:

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 х = {1,0, 2,0}; - может быть такой тип: «DoubleComplex» - это структура, а не массив из двух элементов? –

+0

Правильное наблюдение, конечно. Такое поведение несколько ожидалось. Вопрос в том, что использовать вместо этого, чтобы оно все равно срабатывало. Vala vapi doc также говорит о 'public struct Sth: double {}' например. Но я не могу использовать его для массивов типа 'public struct DoubleComplex: double [2] {}'. –

ответ

2
  1. public struct DoubleComplex: Я не думаю, что вы можете привязать к массиву typedefed C и ожидать Вала, чтобы иметь возможность получить доступ к своим членам или поля.

  2. DoubleComplex x = {1.0, 2.0}; - это инициализация массивов. Вы не сможете использовать эту инициализацию, так как мы не можем допустить, чтобы Вала знал, что ее тип является связанным «непрозрачным» массивом.

Я понимаю, что вы хотите использовать C99 сложные функции, поэтому ниже я представляю мое решение связываться с complex.h. Чтобы сделать сложный заголовок еще более Vala, я бы не писал и VAPI, чтобы связать его напрямую, вместо этого я бы написал стиль на основе объекта оболочки C, набрав double complex, что-то, к чему может привязать Vala.

Сначала я покажу обертку, она состоит из трех файлов:

  • Complex.h для прототипов, ЬурейиХ и включения <complex.h>;
  • Complex.c для реализации функций обертки и;
  • Complex.vapi связаться в Вала.

файл 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); 

файл 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); 
} 

файл 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(); 
    } 
} 

Теперь, когда у вас есть обертку и VAPI, вы можете использовать его в Vala коде:

файл 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()); 
    } 
} 

Для того, чтобы построить и запустить:

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

Представленные примеры выходы:

C Complex Type = 10.000000 20.000000 
+0

Это очень красиво закодированный ответ, спасибо! –

Смежные вопросы