В настоящее время я немного запутался в концепции сокрытия информации в C-структурах.
Фоном этого вопроса является встроенный проект c с почти нулевым знанием ООП.
До сих пор я всегда объявлял свои структуры typedef внутри файла заголовка соответствующего модуля. Таким образом, каждый модуль, который хочет использовать эту структуру, знает тип структуры.
Но после проверки MISRA-C я обнаружил предупреждение средней степени серьезности: MISRAC2012-Dir-4.8 - Реализация структуры без необходимости подвергается воздействию единицы перевода.
После небольшого исследования я обнаружил концепцию сокрытия информации в C-структурах, ограничивая видимый доступ членов структуры частной областью видимости.
Я быстро попробовал простой пример, который звучит так:
struct_test.h
//struct _structName;
typedef struct _structName structType_t;
struct_test.c
#include "struct_test.h"
typedef struct _structName
{
int varA;
int varB;
char varC;
}structType_t;
main.c
#include "struct_test.h"
structType_t myTest;
myTest.varA = 0;
myTest.varB = 1;
myTest.varC = 'c';
Это приводит к ошибке компилятора, что для main.c размер myTest неизвестен. И, конечно же, main.c знает только о существовании структуры типа structType_t и ничего больше.
Итак, я продолжил свои исследования и наткнулся на концепцию непрозрачных указателей.
Итак, я попробовал вторую попытку:
struct_test.h
typedef struct _structName *myStruct_t;
struct_test.c
#include "struct_test.h"
typedef struct _structName
{
int varA;
int varB;
char varC;
}structType_t;
main.c
#include "struct_test.h"
myStruct_t myTest;
myTest->varA = 1;
И я получаю ошибку компилятора: разыменование указателя на неполный тип struct _structName
Очевидно, я не понял основной концепции этой техники. Моя основная путаница заключается в том, где будут данные объекта структуры?
До сих пор я понимал, что указатель обычно указывает на «физическое» представление типа данных и читает / записывает содержимое по соответствующему адресу.
Но с помощью описанного выше метода я объявляю указатель myTest, но никогда не устанавливаю адрес, на который он должен указывать.
Я взял идею из этого сообщения: Что такое непрозрачный указатель в C? а>
В сообщении упоминается, что доступ осуществляется с помощью методов интерфейса set / get, поэтому я попытался добавить что-то подобное:
void setVarA ( _structName *ptr, int valueA )
{
ptr->varA = valueA;
}
Но это также не работает, потому что теперь он говорит мне, что _structName
неизвестно ... Итак, я могу получить доступ к структуре только с помощью дополнительных методов интерфейса, и, если да, как я могу добиться этого в моем простом примере?
И мой более важный вопрос все еще остается, где объект моей структуры находится в памяти. Я знаю только концепцию указателя:
varA - Адрес: 10 - Значение: 1
ptrA - Адрес: 22 - Значение: 10
Но в этом примере у меня есть только
myTest - Адрес: xy - Значение: ??
Мне сложно понять, где находится "физическое" представление соответствующего указателя myTest
?
Более того, я не вижу преимуществ этого в относительно небольших встраиваемых проектах, где я являюсь производителем и потребителем модулей.
Может ли кто-нибудь объяснить мне, действительно ли этот метод разумен для малых и средних встроенных проектов с 1-2 разработчиками, работающими с кодом? В настоящее время кажется, что приложить больше усилий для создания всех этих методов указателя интерфейса, чем просто объявить структуру в моем заголовочном файле.
заранее спасибо
void *
, который при необходимости приводится к типу реального указателя. - person Ctx   schedule 31.01.2020