ferminolaiz:
Para poder instanciar una clase heredada de la que contiene la función virtual pura, uno debe definir todos esos métodos; sino, el compilador también la definirá como abstracta.
Y la pregunta es: ¿cómo? El problema se ve así:
virtual size_t write(uint8_t) = 0;
El "= 0" es el que la vuelve abstracta (virtual pura); seguramente por ser la base del resto de funciones. No todos los "streams" colocan bytes de la misma manera.
Ese no debería ser un problema, se supone que ya tengo una implementación así:
bool write(int b);
Pero el detalle es: ¿cómo combino una cosa con la otra para así implementar dicha función como Print y el compilador lo mandan?
ferminolaiz:
sobre lo de las plantillas, te puedo dar una mano, nunca lo implementé más allá de algunas cosas simples
¿Simples como qué? ¿En clases?
No sé que tan difícil es de recrear, pero lo que hacen put y get es recibir una variable por referencia; de esta forma trabaja directamente en la porción de memoria en vez de retornar un valor o hacer una copia. Con el tipo de dato en el parámetro es donde se determina cuántos bytes hay que leer/escribir.
Lo del paso por referencia es interesante, porque por alguna razón no hay que dársela explícitamente; bastaba con el nombre de la variable. Ejemplo:
EEPROM.get(0, variable); // Referencia implícita
EEPROM.get(0, &variable); // Referencia explícita
ferminolaiz:
Habría que buscar en la hoja de datos de alguna SD referencias en cuanto a la detención de la misma
Finalización por hardware se me ocurría que se le enviaba un comando que lo reiniciase por completo, hasta el punto de necesitar ponerlo en modo SPI otra vez. De no existir, no queda de otra que apagar el sistema o retirar la tarjeta.
Si el medio físico ya se inicializó pero el objeto de Sd2Card no lo ha registrado así todavía, ¿reintentarlo en ese estado haría que el proceso falle? De ser así, entonces obligaría al usuario a retirar la tarjeta; caso contrario, se podría re-inicializar sin sacar nada.
Si Sd2Card no implementa método de finalización alguno, entonces no me queda más remedio que destruirlo y crear otro nuevo.
Esta característica debería servir para dar una "extracción segura"; permitiendo el cambio "en caliente".
De hecho, en mi librería básicamente todo es inservible hasta que la tarjeta sea inicializada correctamente (eso incluye que se pueda reconocer la capacidad de la misma; si no se puede, no cuenta).
ferminolaiz:
la mayoría de las veces no lo hace; o sólo compila el script principal (el .ino).
Si no le he cambiado absolutamente nada, no debería recompilar aún después de la verificación.
ferminolaiz:
Si uno está testeando una biblioteca, a veces pueden generarse problemas a partir de este caché, que no recompila las bibliotecas usadas a pesar de que uno recompile el script.
Con la IDE de Arduino aparentemente no hay problemas con eso; o al menos es así cuando todos los archivos están en la misma carpeta, de lo contrario los errores de compilación no cambiarían cada vez que intento corregir algo.
ferminolaiz:
pero tengo entendido (estoy casi seguro) que al compilar, si el .ino no cambió, no se recompila absolutamente nada.
Eso es lo que digo yo :I
ferminolaiz:
¿Qué versión de la IDE estás usando?
1.6.7
ferminolaiz:
Nunca lo había visto utilizado para instanciar una clase; en realidad, ni siquiera de caer en a qué te refieres con autoinstanciar, a menos que sea crear una sola instancia global (estática, en realidad) de la clase (estilo el objeto Serial).
Esa es la idea.
"Autoinstanciar" está claro que no es un "término estandarizado", pero creo que habla por sí solo: significa que en la declaración de la clase (archivo.h) hay una instancia de sí misma. No en realidad dentro de la declaración, sino que dentro del mismo archivo y antes del último #endif
PDs:
Si logramos resolver el tema de put y get, pondré a prueba una característica que acabo de introducir: parseInt y parseFloat. Así es, esos que convierten texto a binario (variable) directamente desde el "stream" (toda la memoria de la tarjeta). Luego print y println hasta resolver lo de "virtual puro".
Cuando analicen mi librería, quizá más de uno me venga con que estoy "reinventando la rueda", y tienen razón.
En mi defensa, lo que no me gusta de Stream, es que las lecturas las hace con "timeout"; eso estaría bien pero cuando la longitud del "stream" es cambiante (ej.: el búfer de entrada del puerto serie). Pero para trabajar una tarjeta SD en forma "cruda", donde la capacidad (longitud del "stream") solo puede cambiar cambiando el medio físico... un "timeout" más bien entorpece el rendimiento del sistema.
Aquí es donde me doy cuenta que solo he tocado la punta del iceberg de C++.
En parte es irónico: manejo bien el tema de los flujos (de bytes), punteros de memoria y todo lo básico; pero nunca puedo crear una librería sin comenzar con al menos 3 errores de compilación.
En caso de que preguntes... este no es mi primer lenguaje de programación; de hecho, vengo de Java y no porque quise, sino porque en la universidad en la que estudio, se trabaja con ese lenguaje.