【问题标题】:Parameters to use in a Vapi definition for passing arrays by reference在 Vapi 定义中用于通过引用传递数组的参数
【发布时间】:2013-05-27 19:38:28
【问题描述】:

我有以下 C 代码,它使用 libmodbus 来读取使用 ModbusTCP 的单个设备寄存器:

modbus_t *ctx;
uint16_t tab_reg[16];

ctx = modbus_new_tcp("10.0.1.77", 502);
modbus_read_registers(ctx, 0x20, 2, tab_reg);

printf("reg = %d (0x%X)\n", tab_reg[0], tab_reg[0]);
printf("reg = %d (0x%X)\n", tab_reg[1], tab_reg[1]);

现在尝试使用我生成的 Vapi 将其切换到 Vala,new 和 read 的内容是:

[CCode (cheader_filename = "modbus.h", cname = "modbus_new_tcp")]
public static unowned Modbus.modbus_t create_tcp (string ip_address, int port);

public static int read_registers (Modbus.modbus_t ctx, int addr, int nb, uint16 dest);
[CCode (cheader_filename = "modbus.h")]

翻译出来的 Vala 程序是:

class ModbusReadTest : GLib.Object {

    unowned Modbus.modbus_t ctx;

    public void run () {
        uint16 reg = 0x00;

        ctx = create_tcp ("10.0.1.77", 502);
        Modbus.read_registers (ctx, 0x20, 2, reg);

        message ("reg = %d (0x%X)", reg, reg);

        Modbus.close(ctx);
    }
}

巧合的是,当我将它编译成 C 代码,然后使用 gcc 编译成二进制文件时,我得到了错误:

read-registers-test.c:71:2: warning: passing argument 4 of ‘modbus_read_registers’ makes pointer from integer without a cast [enabled by default]

这并不奇怪。但我不确定我应该如何修改 Vapi 内容以更接近 libmodbus 标头中的原型:

int modbus_read_registers(modbus_t *ctx, int addr, int nb, uint16_t *dest);

我尝试过混合使用数组选项并使用“out”,但一次只能获得一个双字节寄存器。

感谢您的任何建议。

【问题讨论】:

    标签: vala modbus vapi


    【解决方案1】:

    read_registers 可能应该是实例方法(在 Modbus.modbus_t 上)而不是静态方法,并且 Modbus.modbus_t 可能应该重命名为 Modbus.Context 之类的东西,create_tcp 可能应该是构造函数,而 Modbus.close应该是 Modbus.Context 紧凑类上的一个免费功能,但这不是这个问题的重点(如果您在 irc.gnome.org 上通过#vala 停下来,您可以获得有关这些东西的帮助)。

    你可能想把它变成一个数组:

    public static int read_registers (Modbus.modbus_t ctx, int addr, [CCode (array_length_pos = 2.5)] uint16[] dest);
    

    然后你会在 Vala 中做这样的事情:

    public void run () {
        uint16 reg[2];
    
        ctx = create_tcp ("10.0.1.77", 502);
        Modbus.read_registers (ctx, 0x20, reg);
    
        message ("reg = %d (0x%X)", reg, reg);
    
        Modbus.close(ctx);
    }
    

    对于更忠实于原始 C 的端口(其中 tab_reg 有 16 个元素而不是 2 个),您可以使用数组切片:

    public void run () {
        uint16 reg[16];
    
        ctx = create_tcp ("10.0.1.77", 502);
        Modbus.read_registers (ctx, 0x20, reg[0:2]);
    
        stdout.printf ("reg = %d (0x%X)\n", reg, reg);
    
        Modbus.close(ctx);
    }
    

    请注意,如果将其设为实例方法,则需要将 array_length_pos 更改为 1.5。

    【讨论】:

      猜你喜欢
      • 2011-12-15
      • 2010-10-07
      • 1970-01-01
      • 2019-02-12
      • 2021-12-11
      • 2017-10-04
      • 1970-01-01
      • 2011-08-09
      相关资源
      最近更新 更多