【问题标题】:How to use a fixed size C array type in vala?如何在vala中使用固定大小的C数组类型?
【发布时间】:2017-01-17 15:22:27
【问题描述】:

假设我有一个 C 代码 (dcomplex.h):

typedef double dcomplex[2];

并且想在 vala 中使用这样的数据类型。 什么是最小的 vapi 文件和 vala 调用它?

(最终目标是使用 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]);
                                 ^^^^

【问题讨论】:

  • 双复数 x = {1.0, 2.0}; - 可能是这种类型:“DoubleComplex”是一个结构,而不是 2 个元素的数组?
  • 这是正确的观察,当然。这种行为在某种程度上是意料之中的。问题是改用什么,以便它无论如何都能工作。例如,vala vapi 文档还说public struct Sth : double {}。但我不能将它用于像public struct DoubleComplex : double[2] {} 这样的数组。

标签: vala vapi


【解决方案1】:
  1. public struct DoubleComplex:我认为您不能绑定到类型定义的 C 数组并期望 Vala 能够访问其成员或字段。

  2. DoubleComplex x = {1.0, 2.0}; 是数组的初始化。您将无法使用此初始化,因为我们无法让 Vala 知道它的类型是绑定的“不透明”数组。

我了解您想要使用 C99 复杂功能,因此,下面,我将介绍我的解决方案以绑定到 complex.h。为了使复杂的标头更适合 Vala,我不会编写和 VAPI 直接绑定它,而是编写一个基于 C 包装器对象的样式 typedefing double complex 到 Vala 可以绑定的东西。

首先我将展示包装器,它由三个文件组成:

  • Complex.h 用于原型、typedef 和包含 <complex.h>
  • Complex.c 用于实现包装函数和;
  • Complex.vapi 在 Vala 中绑定。

文件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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-07-11
    • 2011-06-18
    • 2021-10-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-11-15
    • 1970-01-01
    相关资源
    最近更新 更多