3

libmodbus を使用して、ModbusTCP を使用して単一のデバイス レジスタを読み取る次の C コードがあります。

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」を使用してみましたが、一度に複数の 2 バイト レジスタを取得できませんでした。

提案をありがとう。

4

1 に答える 1

6

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 の要素が 2 ではなく 16 である) により忠実な移植の場合、配列スライスを使用できます。

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 に変更する必要があることに注意してください。

于 2013-05-27T21:53:28.390 に答える