gpt4 book ai didi

c - 仅使用一个函数更新全局 C 结构而不传递整个数据结构

转载 作者:行者123 更新时间:2023-11-30 17:04:25 24 4
gpt4 key购买 nike

我正在开发一个数据库访问层来存储软件子系统的数据。数据库接口(interface)有两个函数:database_get()database_set()。它们采用两个参数,第一个是标识软件组件的 ID,第二个参数是保存该软件组件新设置的 typedef 结构。然后我有:

#define COMPONENT1_ID 7
typedef struct
{
int member1;
char member2;
char member3;

} COMPONENT1_STRUCT_T ;

我可以调用 database_set(COMPONENT1_ID, (void *) &new_struct)database_get(COMPONENT1_ID, (void *) &new_struct) 函数来存储和检索持久数据。使用此数据库存储来自任何其他软件子系统的数据的工作方式相同。

现在我正在开发 API 来管理这个软件子系统。该 API 由用户界面使用。软件子系统的 API 负责执行组件背后的所有逻辑,并调用数据库以使其数据持久化。我为 API 开发了一个函数,它执行操作并最终调用如下函数:

int save_new_member1_db(int member1);
{
COMPONENT1_STRUCT_T new_setting;

database_get(COMPONENT1_ID, (void *)&new_setting);
new_setting.member1 = member1;
database_set(COMPONENT1_ID, (void *)&new_setting);
}

我想知道是否可以避免创建一个新函数来更新数据库中的每个成员数据。

此外,我不希望一个大函数占用整个结构或结构的所有成员,因为这意味着子系统 API 会简化为一个函数。子系统可以是 LED 显示屏,其 API 可以是执行同一操作的不同方法,例如 update_led_display_color(const LED_DISPLAY_COLOR new color)、update_led_display_font(const LED_DISPLAY_FONT cur_font)get_led_display_font(LED_DISPLAY_FONT *cur_font) ...

最佳答案

您将需要在表示成员的符号常量和设置该成员所需的信息之间进行某种映射。您可以为每个成员使用类似“COMPONENT1_ID”的内容,并为每个成员提供一系列大小+偏移信息,如下所示:

#include <stdio.h>
#include <stddef.h>
#include <string.h>

// in header file (or wherever so that it is visible to
// the definition of "Test_save_member" and not a part of
// the subsystem API)
#define TEST_ID 7


// in a c file (in your database implementation, I assume)
typedef struct
{
int mem1;
char mem2;
char mem3;
} Test;

// for sure in header file exposed in your subsystem API
typedef enum
{
MEM1,
MEM2,
MEM3,
NUM_MEMBERS
} TestMember;

// in c file (in your database implementation, I assume again)

typedef struct
{
size_t offset;
size_t size;
} MemberInfo;

static MemberInfo member_info[NUM_MEMBERS] =
{
{ offsetof(Test, mem1), sizeof(int) },
{ offsetof(Test, mem2), sizeof(char) },
{ offsetof(Test, mem3), sizeof(char) }
};

// also a part of your subsystem API
int Test_save_member(TestMember member, void* value)
{
if (!value || member < 0 || member >= NUM_MEMBERS))
return 0;

Test new_setting;
database_get(TEST_ID, (void *)&new_setting);
MemberInfo info = member_info[member];
memcpy((char*)(&new_setting) + info.offset, value, info.size);
database_set(TEST_ID, (void *)&new_setting);
return 1;
}

// subsystem API usage
int main(void)
{
int new_mem1 = 5;
Test_save_member(MEM1, &new_mem1);
return 0;
}

根据您是否要编辑数据库函数、要处理的耦合量等,这可能会发生巨大变化;但是,我认为考虑到您提到的限制,您无法在没有某种类型的映射的情况下逃脱。

这个特定的实现将不允许传递文字,但这不应该是一个太大的问题(处理或解决)。

关于c - 仅使用一个函数更新全局 C 结构而不传递整个数据结构,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/35818115/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com