C从不同结构的数组中获取并实例化结构类型

时间:2017-12-05 22:50:50

标签: c arrays struct

我很难搞清楚这一点......

我有一堆结构来定义数据流中的消息类型,如下所示:

struct QM_lUpdP
{
    char type [6];
    char exchange_id [6];
    char currency_id [4];
    char hour [3];
    char minute [3];
    char second [3];
    char millisecond [4];
    char instrument_type [3];
    char order_reference [31];
    char price_type [2];
    char price [11];
    char mmid [5];

} QM_lUpdP;

其中许多都有不同的名称和格式。

我想要能做的是......动态地,给定一个结构名称,获取并实例化该结构,到目前为止我都是这样做的。

char data_struct_names[NUMBER_OF_MESSAGE_TYPES + 1][16] = {
    "QM_BkCan",
    "QM_BkChg",
    "QM_BkDel",
    "QM_BkExc",
     ...
    "QM_lEquI",
};

void * QM_get_data_struct (char * struct_name)
{
    void * data_structs [NUMBER_OF_MESSAGE_TYPES + 1] = {
        &QM_BkCan,
        &QM_BkChg,
        &QM_BkDel,
        &QM_BkExc,
        ...
        &QM_lEquI
    };

    for (int i = 0; i < NUMBER_OF_MESSAGE_TYPES; i++)
    {
        if (strcmp(data_struct_names[i], struct_name) == 0) return data_structs[i];
    }

    fprintf( stderr, "%s is an invalid or unimplemented struct!!\n", struct_name);
    return (void *)0;
}

因此,给定一个名称,我们可以搜索名称列表,找到索引,然后从具有相同索引的结构列表中获取该结构。

现在,我只是返回一个void指针,它根据结构返回一个可靠的地址。有没有办法解开这个指针并将其用作结构?

...如何实例化它并在代码中使用它。这甚至是可能的,因为结构的类型是未知的,所以我不能做......

QM_BkCan data = QM_get_data_struct("BkCan");

这甚至可能吗?我应该以不同的方式接近这个吗?

Ideally I would have...

data_struct = get_struct(NAME_STRING);

data_struct.value = "hello!";

printf("%s", data_struct.value); // hello!

谢谢。

1 个答案:

答案 0 :(得分:1)

C中无法满足您的需求。

我认为你可能需要以不同的方式做到这一点。你可以这样做:

struct QM_BkCan {
    ...
}
struct QM_BkChg {
    ...
}
struct QM_BkDel {
    ...
}
struct QM_BkExc {
    ...
}
struct QM_lEquI {
    ...
}

enum QM_Types {
    QM_Type_BkCan = 0,
    QM_Type_BkChg,
    QM_Type_BkDel,
    QM_Type_BkExc,
    QM_Type_lEquI
}

union QM_Structs {
    struct QM_BkCan QM_BkCan;
    struct QM_BkChg QM_BkChg;
    struct QM_BkDel QM_BkDel;
    struct QM_BkExc QM_BkExc;
    struct QM_lEquI QM_lEquI;
}

由于您需要使用动态字符串,您可以使用您的函数(但已修改):

char data_struct_names[NUMBER_OF_MESSAGE_TYPES + 1][16] = {
    "QM_BkCan",
    "QM_BkChg",
    "QM_BkDel",
    "QM_BkExc",
    "QM_lEquI",
};

enum QM_Types QM_get_data_struct (char * struct_name)
{
    for (int i = 0; i < NUMBER_OF_MESSAGE_TYPES; i++)
    {
        if (strcmp(data_struct_names[i], struct_name) == 0)
            return (enum QM_Types)((int)QM_Type_BkCan + i);
    }

    fprintf( stderr, "%s is an invalid or unimplemented struct!!\n", struct_name);
    return (void *)0;
}

然后,您可以按如下方式使用它:

struct QM_Structs * s = (QM_Structs *)your_data_array;

switch (QM_get_data_struct(YOUR_STRING)) {
    case QM_Type_BkCan:
        s->QM_BkCan.something = something_else;
        break;
    case QM_Type_BkChg:
        s->QM_BkChg.something = something_else;
        break;
    ...
}

这不是一个很好的方式,但我不相信还有其他办法。