2015-11-06 46 views
0

我在库中有两个结构体,我无法更改。 p.e:使struct数组指向另一个struct Array

struct{ 
    uint8_t test; 
    uint8_t data[8]; 
}typedef aStruct; 

struct{ 
    uint8_t value; 
    uint8_t unimportant_stuff; 
    char data[8]; 
}typedef bStruct; 

aStruct a; 
bStruct b; 

在我的应用程序中有一个过程,permantently刷新我的aStruct的。 现在我有一个bStruct的缓冲区,我想保持更新。 数据[]数组是重要的领域。我并不关心结构的其他价值。

我已经确定,在代码运行的特定系统上,“char”也是8Bits。

现在我想让“b.data”数组指向与我的“a.data”数组完全相同的值。所以如果进程刷新我的aStruct,我的bStruct中的值也是最新的。

因此,在C数组只有一个指向第一个元素,我觉得这样的事情一定是可能的:

b.data = a.data 

但不幸的是这给我的编译器错误:

error: assignment to expression with array type

有没有办法做我打算做的事情?

在此先感谢

+0

那不是这是如何工作的。分配'a.data [0] =(char)b.data [0]'等等。如果你喜欢,可以使用for循环。 – Magisch

+0

在'bStruct'中,您需要将'char data [8]'更改为'char * data',所以答案是否定的。 – user3386109

+0

数组不指向数据。并且不可分配。查看如何复制数组,应该有许多重复项。 – juanchopanza

回答

0

如果你想b.data[]阵列指向完全相同的值,那么你可以做的b一个char*data并使其指向adata

喜欢的东西

struct{ 
uint8_t value; 
uint8_t unimportant_stuff; 
char* data; 
}typedef bStruct; 

b.data = a.data; 

但是,请记住,这意味着b.data是在相同的存储单元a.data指向,因此,改变b.data值会发生变化值的a.data也。


有这样的另一种方式。它通过将a.data的所有值复制到b.data中。然后,b.data只会包含与a.data相同的值,但它会指向不同的内存位置。

这可以通过逐个复制来完成。在所有8元素的for循环中。

或者,要使用memcpy()


注意

数组不能进行指向另一个存储位置。因为它们是不可修改的l值。如果您不能修改struct,那么您必须使用第二种方法。

+0

这正是我想要做的......问题是,我无法更改结构(都定义在库中) –

+1

@TomMekken,那么你将不得不采用第二种方法。因为不能使数组指向其他内存位置。他们是**不可修改的l值** – Haris

+0

是的,但我没有通知有关更新。所以我不知道什么时候复制这些值...因此我想要指针。好的,所以没有“真正的”指针似乎没有办法做到这一点。 –

1

好的,根据我从你们那里得到的意见,我认为这可能是重新设计我的应用程序的最佳方式。

因此,而不是缓冲区的bStruct的我可能会使用aStruct *的缓冲区。这可以确保我的缓冲区始终处于最新状态。然后,如果我需要使用缓冲区的某个元素进行操作,我会写一个简短的getter函数,它将aStruct *中的数据复制到临时bStruct中并返回。

感谢您的回复和评论。

+0

谢谢你写下! – fuz

0

当你无法修改现有的结构定义时,你所要求的是不可能的。但是,您仍然可以通过一些OO风格的编程来自动执行功能。以下所有内容假定结构中的数据字段长度相同,并且包含相同大小的元素,如示例中所示。

基本上,你用自己的容器包装现有的结构。你可以把这个头文件:

/* Forward declaration of the wrapper type */ 
typedef struct s_wrapperStruct wrapperStruct; 
/* Function pointer type for an updater function */ 
typedef void (*STRUCT_UPDATE_FPTR)(wrapperStruct* w, aStruct* src); 
/* Definition of the wrapper type */ 
struct s_wrapperStruct 
{ 
    STRUCT_UPDATE_FPTR update; 
    aStruct* ap; 
    bStruct* bp; 
}; 

然后你就可以可以创建你用它来创建您的同步结构对避免同步逻辑暴露给感兴趣各方工厂式的模块。实现一些简单的功能。

/* The updater function */ 
static void updateStructs(wrapperStruct* w, aStruct* src) 
{ 
    if ((w != NULL) && (src != NULL)) 
    { 
     /* Copy the source data to your aStruct (or just the data field) */ 
     memcpy(w->ap, src, sizeof(aStruct)); 
     /* Sync a's data field to b */ 
     sync(w); /* Keep this as a separate function so you can make it optional */ 
    } 
} 

/* Sync the data fields of the two separate structs */ 
static void sync(wrapperStruct* w) 
{ 
    if (w != NULL) 
    { 
     memcpy(w->bp->data, w->ap->data, sizeof(w->bp->data)); 
    } 
} 

然后在你的工厂函数可以创建包裹对。

/* Create a wrapper */ 
wrapperStruct syncedPair = { &updateStructs, &someA, &someB }; 

然后,您可以在需要的地方通过,例如,正在更新您的aStruct,并使用它像这样的过程:

/* Pass new data to the synced pair */ 
syncedPair.update(&syncedPair, &newDataSource); 

因为C不是被设计成一个面向对象的语言,它不具有this指针,你需要通过明确的包装围绕指针。从本质上讲,这就是C++幕后的情况,编译器为您节省了额外的麻烦。

如果您需要将单个aStruct同步到多个bStruct s,将指针更改为数组指针并相应地修改其余部分应该非常简单。

这可能看起来像一个过于复杂的解决方案,但是当您实现逻辑一次时,它可能会帮助您节省维护中的一些体力劳动。