Как использовать тип массива фиксированного размера C в Vala?
Предположим, у меня есть код C (dcomplex.h):
typedef double dcomplex[2];
и хочу использовать такой тип данных в Vala. Каким может быть минимальный 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]);
^^^^
1 ответ
public struct DoubleComplex
Я не думаю, что вы можете связываться с массивом C с определением типа и ожидать, что Vala сможет получить доступ к его элементам или полям.DoubleComplex x = {1.0, 2.0};
это инициализация массивов. Вы не сможете использовать эту инициализацию, так как мы не можем дать Vala знать, что его тип - это "непрозрачный" массив.
Я понимаю, что вы хотите использовать сложные функции C99, поэтому ниже я представляю свое решение для привязки к complex.h
, Чтобы сделать сложный заголовок более понятным Vala, я бы не стал писать и VAPI связывать его напрямую, вместо этого я бы написал определение типа стиля на основе обертки C double complex
к чему-то, что Вала может связать.
Сначала я покажу обертку, она состоит из трех файлов:
Complex.h
для прототипов, typedef и включение<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