# código C en Matlab, no compila



## sandry (Ago 11, 2010)

Hola, estoy haciendo un proyecto final de carrera con la planta piloto PCT23 MKII AMFIELD ( es una maqueta de una planta de pasteurización )y tengo un problema :
La planta se conecta al ordenador mediante USB y quiero saber como puedo leer desde Matlab las variables de la planta (temperatura, caudal ... ) para poder actuar con ellas y hacer un Control. 
He creado un fichero .mex compilado con C para la lectura de datos de la planta, pero al ejecutarlo con Matlab no asigna como variables esos datos. 
Os agradeceria si alguien pudiese darme información sobre este tema, contestadme y me pongo en contacto con vosotros. 


Si alguien sabe programación en C o Matlab, me gustaría que nos ayudasen a descifrar el siguiente programa :
#include "mex.h" 

long CReadAnalog(long channel);
void mexFunction(int nlhs, mxArray *plhs[], int nrhs, const mxArray *prhs[] ) 
{ 
int i; 
long ans; 
mexPrintf("\n - Armfield IFD5 - \n\n Analogue Channels \n\n"); 
i = 1; 
while (i < 9) 
{ 
ans = CReadAnalog(i-1);
mexPrintf(" AI %i: %d\n",i, ans); 
i = i + 1; 
} 
} 

Y más concretamente la instrucción de

*long CReadAnalog(long channel);*

ya que es la que nos da error a la hora de compilar . 

Muchas gracias.


----------



## Eduardo (Ago 11, 2010)

long CReadAnalog(long channel);

Es la declaración de una función. 
Puede estar su definición en algún include o puede estar compilada dentro de una libreria y simplemente no la encuentra.


----------



## wacalo (Ago 11, 2010)

ans = CReadAnalog(i-1);
Solo por dar una pista: Quizás (solo quizás) puede ser un problema el hecho de que estés llamando a la función con un argumento de tipo int cuando la función está definida para aceptar un tipo long.
Saludos


----------



## willynovi (Ago 11, 2010)

mas que saber C habria que ser tambien adivino, jeje.

Especificamente cual es el error que te está dando cuando compilas, eso te servirá mucho para poder acomodar el código y que funcione.

si el error esta en lo que indica wacalo, el compilador te daria un error como que CReadAnalog no admite una variable int como argumento, o algo similar. Si fuera así lo que puedes hacer es una conversión.

ans = CReadAnalog(long(i)-1);

Este código lo haces en un compilador de C, como Borland, o dentro del MatLab? No he trabajado con MatLab, pero el problema quizas sea que no encuentra la función como te indicaba Eduardo.

Tambien revisa el mex.h y seguramente habrá algun otro archivo que tienes el contenido de CReadAnalog.
Ahi seguro puedes ver y estudiar que hace cada función y que significa cada argumento que tome.


----------



## Eduardo (Ago 11, 2010)

sandry dijo:


> Y más concretamente la instrucción de
> *long CReadAnalog(long channel);*
> ya que es la que nos da error a la hora de compilar .


Ah!  Los mensajes de error están para leerlos, no para decir solamente "nos da error".


----------



## sandry (Ago 11, 2010)

Gracias por vuestras respuestas.
Os comento el porqué de este programa. Tenemos que comunicar una planta piloto al ordenador y el programa que lee los datos nos lo madaron predefinido y es el que os he puesto ahi arriba. 
Como queremos hacer un control con esas variables, necesito almacenarlas en el espacio de trabajo de Matlab para trabajar con ellas, por eso tengo que modificar el programa y aqui es donde vienen las complicaciones.
Vuestros comentarios creo que van bien encaminados, pues el error que nos da a la hora de compilar es el siguiente : 

*error C2085: 'CReadAnalog' : no esta en la lista de parametros formales.
Warning C4013: 'CreadAnalog' sin definir; se supone que extern devuelve como resultado int (...)*

Lo que me comentais de las librerias ya nos lo han comentado también. Junto al programa nos mandaron estas :

- 2008_armifd.lib
- ARMIFD.def
- ArmIFD.lib
- ArmIFD.dll

Pero no sabemos donde incluirlas, hemos probado en la Carpeta 'bin' , pero sigue dandonos error.
También nos han dicho que deberia haber un include como ' #include "mex.h" ' pero con la la libreria que contubiese al CReadAnalog.
Espero haberme explicado mejor, y que sigais opinando ya que me estais dando mucha informacion e ideas.


----------



## Dr. Zoidberg (Ago 11, 2010)

Cual versión de matlab y compilador estás usando?
Un lugar fácil para poner todo es en el *mismo directorio donde tenés el archivo .m o .mdl*


----------



## sandry (Ago 11, 2010)

La versión de Matlab es la 2007b y el compilador DevC++.


----------



## Dr. Zoidberg (Ago 11, 2010)

Esa no es una combinación muy buena...estás seguro de la compatibilidad entre ambos?
Normalmente el Matlab *no solía detectar al gcc* instalado y solo funcionaba bien con el Visual Studio 6.0 o con el Watcom nomeacuerdocualversión o superiores...pero no tan superiores, al menos en versiones anteriores a esa.
Tenés que averiguar cual es la dependencia de lo que querés compilar con esas bibliotecas que te han dado, por que unas son para enlaces estáticos (.lib) y otras para dinámicos (.dll) y los mex-files nuevos compilados bajo Matlab usan DLLs, así que no creo que te sirvan los .lib
Una pregunta: estás compilando desde Matlab, no? con el comando mex..???


----------



## sandry (Ago 11, 2010)

No, no sabia nada de la compatibilidad. Sabiamos lo básico de Matlab que se estudia en la carrera, pero es ahora con el proyecto cuando tenemos que aprender a fondo, y la verdad es que estamos un poco perdidos, hemos estudiado el manual de Aprende Matlab como si estubieses en primero, pero también es muy básico.
Estamos guiandonos con la ayuda de Matlab y si, compilamos con Matlab utilizando :

-mex mexfunction.c


----------



## Dr. Zoidberg (Ago 11, 2010)

Pues entonces vas a tener que revisar el help o mirar en el foro de Mathworks como se hace con el DevC++, por que el problema que tenés es que has puesto el prototipo de la función CReadAnalog...pero lo has agregado vos...y eso debería venir en un archivo .h declarado como extern para que el compilador sepa que el código no está en el mismo archivo fuente y sepa hacer el enlace dinámico o estático que corresponda.
No te digo que revises en los directorios de instalación de Matlab por que tiene unos scripts en lenguaje Matlab o en Perl para generar los makefiles de compilación...y ahí van a comenzar tus problemas.
Tengo la impresión que lo que te han dado para usar está incompleto...o al menos no está hecho para usarlo desde Matlab.

Podés copiar el archivo .def para ver cuales son las funciones exportadas por la DLL? (encerralo entre etiquetas 
	
	



```
con el icono del editor para que sea vea bien).
```


----------



## sandry (Ago 11, 2010)

El archivo ArmIFD. def abierto con el bloc de notas es el siguiente :

*LIBRARY ArmIFD
EXPORTS
CReadAnalog
CReadDigital
CReadFrequency
CReadHS
CSetDAC
CSetMode
CWriteAnalogs
CWriteDigitals
ReadAnalog
ReadDigital
ReadFrequency
ReadHS
SetDAC
SetMode
WriteAnalogs
WriteDigitals*


----------



## Dr. Zoidberg (Ago 11, 2010)

Bueno, te las vas a tener que ingeniar para que el compilador enlace tu código de la mexfunction con el ArmIFD.lib o el ArmIFD.dll, y vas a tener que declarar el prototipo de la CReadAnalog como *extern *para que no te tire los errores que te aparecen ahora. Hacé esto primero y fijate que error tira el compilador.


----------



## sandry (Ago 11, 2010)

Ok, voy ha intertarlo y ya te cometaré qué tal ... muchas gracias.


----------



## Dr. Zoidberg (Ago 11, 2010)

Ya me fijé en el help del comando MEX, y le podés dar, junto con el nombre del .c a compilar, el nombre y ruta de los .lib para que los enlace.


----------



## sandry (Ago 11, 2010)

Eso hemos intentado esta mañana, hemos intentado compilarlo de esta forma :
*- mex mexfunction.c -l armifd.lib*
pero nos seguía dando el mismo error.


----------



## Dr. Zoidberg (Ago 11, 2010)

sandry dijo:


> Eso hemos intentado esta mañana, hemos intentado compilarlo de esta forma :
> *- mex mexfunction.c -l armifd.lib*
> pero nos seguía dando el mismo error.



Es que si no declarás la función CReadAnalog como extern el error te lo va a dar siempre, por que la busca en el archivo .c y no está definida ahí, está en el .lib 
Tenés que hacer las dos cosas:


Declararla como *extern*
Decirle que use la *armifd.lib* en la invocación al compilador con el comando MEX.
Y tenés que hacerlo en ese orden....y rogar que ese .lib no esté compilado para procesador ARM, por que hasta el nombre me resulta sospechoso...


----------

