1

libbeanstalkd を組み込みシステムに統合しようとしているので、小さな変更を加える必要があります。これまでのところ、OS 固有のコードの一部を置き換え/修正することができましたが、このエラーが発生しました。「式は完全なオブジェクト型へのポインターである必要があります」の前にこれらのタイプのエラーを修正しましたが、マクロと使用されたオブジェクトのヘッダーがこのマクロが使用されていることを確信しているという事実を除けば、本当に私を惹きつけているのは何ですかコンパイラエラーがスローされる数行前。誰かが問題の内容を理解するのを手伝ってくれますか?

ソースarrayqueue.h

#ifndef ARRAYQUEUE_H
#define ARRAYQUEUE_H 

#define AQ_DEFINE_STRUCT(struct_name, node_type) \
struct struct_name {                             \
    node_type *nodes;                            \
    size_t     size;                             \
    size_t     used;                             \
    off_t      front;                            \
    off_t      rear;                             \
}

#define AQ_NODES_FREE(q) ( (q)->size - (q)->used )
#define AQ_FULL(q)       ( (q)->used == (q)->size )
#define AQ_EMPTY(q)      ( (q)->used == 0 )

#define AQ_REAR_(q)      ( (q)->nodes + (q)->rear )
#define AQ_REAR(q)       ( AQ_EMPTY(q) ? NULL : AQ_REAR_(q) )

#define AQ_FRONT_(q)     ( (q)->nodes + (q)->front )
#define AQ_FRONT(q)      ( AQ_FULL(q) ? NULL : AQ_FRONT_(q) )

#define AQ_DEQ_FIN(q)    ( (q)->rear  = ( (q)->rear  + 1 ) % (q)->size, (q)->used-- )
#define AQ_ENQ_FIN(q)    ( (q)->front = ( (q)->front + 1 ) % (q)->size, (q)->used++ )

#endif /* ARRAYQUEUE_H */

出典ioqueue.h

#ifndef _IOQUEUE_H
#define _IOQUEUE_H

#include <stddef.h>
#include <vsocket.h>
#include "arrayqueue.h"
#include "verixmissing.h"

struct _ioq_node {
    struct iovec *vec;
    int    autofree;
};

AQ_DEFINE_STRUCT(_ioq, struct _ioq_node);

typedef struct _ioq ioq;
typedef struct _ioq_node ioq_node;

#define IOQ_NODES_READY(q)   ((q)->used ? ( (q)->front <= (q)->rear ? (q)->size - (q)->rear : (q)->used ) : 0)
#define IOQ_PEEK_POS(q, i)   ((AQ_REAR_(q)+i)->vec)
#define IOQ_REAR_(q)         IOQ_PEEK_POS(q,0)
#define IOQ_REAR(q)          (AQ_EMPTY(q) ? NULL : IOQ_REAR_(q))

void    ioq_enq_(ioq *q, void *data, ssize_t data_len, int autofree);
int     ioq_enq(ioq *q, void *data, ssize_t data_len, int autofree);
ssize_t ioq_dump(ioq *q, int fd);
ioq    *ioq_new(size_t size);
void    ioq_free(ioq *q);

#endif /* _IOQUEUE_H */

出典ioqueue.c

#include <stdlib.h>
#include <vsocket.h>
#include "arrayqueue.h"
#include "ioqueue.h"

...

ssize_t ioq_dump(ioq *q, int fd)
{
    size_t  bytes_expected = 0, nodes_ready = IOQ_NODES_READY(q), i;
    ssize_t bytes_written, nodes_written  = 0;

    for (i = 0; i < nodes_ready; ++i)
        bytes_expected += IOQ_PEEK_POS(q,i)->iov_len;

    if ( ( bytes_written = writev(fd, IOQ_REAR_(q), nodes_ready) ) < bytes_expected )
        switch (bytes_written) {
            case -1:
                return -1;
            default:
                while ( ( bytes_written -= IOQ_REAR_(q)->iov_len ) > 0 ) {
                    IOQ_DUMP_FIN(q, 1);
                    ++nodes_written;
                }
                if ( bytes_written < 0 ) {
                    IOQ_REAR_(q)->iov_base += IOQ_REAR_(q)->iov_len + bytes_written;
                    ^---------------------- ERROR!
                    IOQ_REAR_(q)->iov_len   = -bytes_written;
                }
                return nodes_written;
        }
    else {
        IOQ_DUMP_FIN(q, nodes_ready);
        return nodes_ready;
    }
}

エラー:

"..\Source\libs\libbeanstalkd\ioqueue.c", line 125: Error:  #852: expression must be a pointer to a complete object type
                    IOQ_PEEK_POS(q, 0)->iov_base += IOQ_REAR_(q)->iov_len + bytes_written;
                    ^

それが役立つ場合、Eclipse はマクロを次のように展開します。((( (q)->nodes + (q)->rear )+0)->vec)

4

2 に答える 2

0

だから私は問題を発見しました...本当の問題は、このメソッドがソケットのバッファのアドレスをインクリメントしようとしているようですが、構造体がiov_base定義されているvoid *ため、コンパイラはインクリメントする方法を知りません。(エラーから答えを得ました: 式は完全なオブジェクト型へのポインタでなければなりません (?) )

iovec 宣言:

struct iovec
{
    void *iov_base; // starting address of buffer
    int iov_len;  // size of buffer
};

解決策は既知の型にキャストすることですが、残念ながら型がわかりません...

于 2013-08-18T18:33:48.423 に答える