如何在vala中使用固定大小的C数组类型?

时间:2017-01-17 15:22:27

标签: vala vapi

假设我有一个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]);
                                 ^^^^

1 个答案:

答案 0 :(得分:3)

  1. import _ from './lodash-mixins'; _.map([]); // built-in function still compiles _.xdiff([], []); // mixin function compiles too :我认为您无法绑定到typedefed C数组,并希望Vala能够访问其成员或字段。

  2. public struct DoubleComplex是数组的初始化。您将无法使用此初始化,因为我们不能让Vala知道它的类型是绑定的"不透明"阵列

  3. 我知道你想要使用C99复杂的功能,所以,下面,我提出我的解决方案绑定到DoubleComplex x = {1.0, 2.0};。为了使复杂的标题更加Vala友好,我不写和VAPI直接绑定它,而是我写了一个基于样式的C包装器对象定义complex.h到Vala可以绑定的东西。

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

    • double complex了解原型,typedef以及Complex.h;
    • 的内容
    • <complex.h>用于实现包装函数和;
    • Complex.c以Vala绑定。

    档案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

    现在您已经拥有了包装器和VAPI,您可以在Vala代码中使用它:

    档案[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 (); } }

    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