Это результат недоразумения: data
НЕ является аксессуаром для атрибутов data-*
. Это и больше, и меньше.
data
является аксессуаром для кэша данных jQuery для элемента. Этот кеш инициализирован из атрибутов data-*
, если есть какие-либо данные, но data
никогда не записывает в атрибуты, а также не изменяет атрибут кэша данных после инициализации .
data
также массирует то, что он находит по-разному, угадывая типы данных, делая data("foo")
на элементе с data-foo="1"
числом, а не строкой или даже анализируя вещи как JSON if они выглядят правильно:
console.log(typeof $("[data-foo]").data("foo"));
console.log(typeof $("[data-bar]").data("bar"));
Если вы хотите использовать атрибуты (как чтение, так и их настройку), используйте attr
, а не data
. attr
является аксессуаром для атрибутов.
К сожалению, компилятор должен знать размер port_t
(в байтах) при компиляции main.c, таким образом, Вам нужно полное определение типа в заголовочном файле.
Общее решение, которое я использую:
/* port.h */
typedef struct port_t *port_p;
/* port.c */
#include "port.h"
struct port_t
{
unsigned int port_id;
char name;
};
Вы используете port_p в функциональных интерфейсах. Необходимо будет создать специальный malloc (и свободный) обертки в port.h также:
port_p portAlloc(/*perhaps some initialisation args */);
portFree(port_p);
Если Вы хотите скрыть внутренние данные port_t
структура, можно использовать технику как то, как стандартная библиотека обрабатывает FILE
объекты. Клиентский код только имеет дело с FILE*
объекты, таким образом, им не нужно (действительно, тогда обычно не может) иметь любой knowlege того, что находится на самом деле в FILE
структура. Недостаток к этому методу состоит в том, что клиентский код не может просто объявить, что переменная имеет тот тип - у них могут только быть указатели на него, таким образом, объект должен быть создан и уничтожил использование некоторого API, и весь , использование объекта должно быть через некоторый API.
преимущество для этого состоит в том, что у Вас есть хороший чистый интерфейс к тому, как port_t
объекты должны использоваться и позволяют Вам сохранить частные вещи частными (нечастные вещи нуждаются в функциях метода get/метода set, чтобы клиент получил доступ к ним).
Точно так же, как, как ФАЙЛОВЫЙ ВВОД-ВЫВОД обрабатывается в библиотеке C.
Я рекомендовал бы другой путь:
/* port.h */
#ifndef _PORT_H
#define _PORT_H
typedef struct /* Define the struct in the header */
{
unsigned int port_id;
char name;
}port_t;
void store_port_t(port_t);/*Prototype*/
#endif
/* port.c */
#include "port.h"
static port_t my_hidden_port; /* Here you can hide whatever you want */
void store_port_t(port_t hide_this)
{
my_hidden_port = hide_this;
}
/* main.c */
#include <stdio.h>
#include "port.h"
int main(void)
{
struct port_t ports;
/* Hide the data with next function*/
store_port_t(ports);
return 0;
}
Это обычно бесполезно для определения переменных в заголовочном файле.