Configurar el archivo .mff
El archivo de funciones de MapForce (.mff) es un archivo de configuración en formato XML que permite adaptar funciones de bibliotecas Java, C# y C++ personales a MapForce para que aparezcan en la ventana Bibliotecas. Un archivo .mff hace de intermediario entre las bibliotecas personales del usuario y MapForce y debe configurarse para especificar las interfaces con las funciones personales y dónde se puede encontrar la implementación en el código generado.
Tenga en cuenta que:
•los archivos de biblioteca *.mff deben ser válidos según el archivo de esquema mff.xsd de la carpeta C:\Archivos de programa\MapForceLibraries\mff.xsd. El esquema mff.xsd define la configuración de biblioteca personal y es para uso interno. Altova GmbH se reserva el derecho de cambiar el formato de este archivo en futuras versiones del software.
•Solamente se puede definir un archivo C#, C++ o .class Java por archivo .mff.
Archivo .mff C# de ejemplo
Este fragmento de código corresponde a un archivo .mff para C++:
<?xml version="1.0" encoding="UTF-8"?>
<mapping version="9" library="mylib" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="mff.xsd">
<implementations>
<implementation language="cpp">
<setting name="namespace" value="mylib"/>
<setting name="class" value="Greetings"/>
<setting name="path" value="C:\Libraries\cpp"/>
<setting name="include" value="Greetings.h"/>
<setting name="source" value="Greetings.cpp"/>
</implementation>
</implementations>
<group name="greetings">
<component name="sayhello">
<sources>
<datapoint name="ismorning" type="xs:boolean"/>
</sources>
<targets>
<datapoint name="result" type="xs:string"/>
</targets>
<implementations>
<implementation language="cpp">
<function name="SayHello"/>
</implementation>
</implementations>
<description>
<short>result = sayhello(ismorning)</short>
<long>Returns "Good morning" or "Good day", depending on the input parameter.</long>
</description>
</component>
</group>
</mapping>
Biblioteca personal importada
La imagen que aparece a continuación muestra el resultado de importar un archivo .mff personal en MapForce. Observe que la biblioteca personal helloworld aparece en la ventana Bibliotecas y que contiene la función de cadena "hello".
Configuración
A continuación encontrará las instrucciones para adaptar el archivo .mff a los requisitos de su proyecto.
Paso 1. Configurar el nombre de la biblioteca
El nombre de la biblioteca está en la línea del archivo .mff que aparece a continuación. El nombre de la biblioteca se escribe en minúsculas.
<mapping version="9" library="mylib" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="mff.xsd">
En este ejemplo, la biblioteca aparecerá en la ventana Bibliotecas de MapForce con el nombre "helloworld".
Paso 2. Configurar las implementaciones del lenguaje
El elemento <implementations> es un elemento obligatorio que especifica con qué lenguajes debe ser compatible la biblioteca y debe ser un secundario de <mapping>. Veamos un ejemplo:
<!-- ... -->
<mapping version="9" library="mylib" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="mff.xsd">
<implementations>
<implementation language="cpp">
<setting name="namespace" value="mylib"/>
<setting name="class" value="Greetings"/>
<setting name="path" value="C:\Libraries\cpp"/>
<setting name="include" value="Greetings.h"/>
<setting name="source" value="Greetings.cpp"/>
</implementation>
</implementations>
<!-- ... -->
Las opciones de cada elemento <implementation> permiten al código generado llamar a las funciones definidas en Java, C++ o C#. Puede configurar el archivo .mff para que apunte a más de un lenguaje de programación. En este caso, cada lenguaje debe contener un elemento <implementation>. Más abajo encontrará información sobre las opciones disponibles para cada lenguaje de programación.
Referencia de la biblioteca Java
<!-- ... -->
<implementation language="java">
<setting name="package" value="com.hello.functions"/>
<setting name="class" value="Greetings"/>
</implementation>
<!-- ... -->
Es importante que el código generado pueda encontrar el archivo Greetings.class. Por tanto, asegúrese de que la clase está en la variable classpath de Java.
Referencia de la biblioteca C#
<!-- ... -->
<implementation language="cs">
<setting name="namespace" value="MyLibrary" />
<setting name="class" value="Greetings" />
<setting name="reference" value="C:\Libraries\cs\MyLibrary\bin\debug\MyLibrary.dll" />
</implementation>
<!-- ... -->
Es importante que el espacio de nombres del código se corresponda con el espacio de nombres definido en el archivo .mff (en el fragmento de código anterior el espacio de nombres es MyLibrary). Lo mismo ocurre con el nombre de la clase (en el fragmento de código anterior el nombre de clase es Greetings). La tercera opción, reference, aporta la ruta de acceso del dll que debe vincularse al código generado.
Referencia de la biblioteca C++
<!-- ... -->
<implementation language="cpp">
<setting name="namespace" value="MyLibrary"/>
<setting name="class" value="Greetings"/>
<setting name="path" value="C:\Libraries\cpp"/>
<setting name="include" value="Greetings.h"/>
<setting name="source" value="Greetings.cpp"/>
</implementation>
<!-- ... -->
En el fragmento de código C++ anterior podemos ver que:
•namespace es el espacio de nombres donde se definirá la clase Greetings. Debe ser igual que el nombre de la biblioteca.
•path es la ruta de acceso donde se encuentran los archivos de inclusión y de origen.
•cuando se genera código para una asignación de datos, los archivos de inclusión y de origen se copian en el directorio targetdir/libraryname (definido cuando se selecciona el comando de menú Archivo | Generar código en C++ y se elije el directorio de destino) y también se incluyen en el archivo de proyecto.
Todos los archivos de inclusión se incluirán en el algoritmo que se genera.
Paso 3. Agregar un componente
En la ventana Bibliotecas de MapForce las funciones aparecen anidadas dentro de un grupo de funciones (p. ej. "string functions"). En el archivo .mff una función corresponde a un elemento <component>. Igualmente, cada <component> debe estar anidado dentro de un elemento <group>. Por ejemplo:
<!-- ... -->
<group name="string functions">
<component name="sayhello">
<!-- ... -->
</component>
</group>
<!-- ... -->
El código que aparece a continuación define un ejemplo de función (componente) llamada sayhello.
<!-- ... -->
<component name="sayhello">
<sources>
<datapoint name="ismorning" type="xs:boolean"/>
</sources>
<targets>
<datapoint name="result" type="xs:string"/>
</targets>
<implementations>
<!-- ... -->
</implementations>
<description>
<short>result = sayhello(ismorning)</short>
<long>Returns "Good morning" or "Good day", depending on the input parameter.</long>
</description>
</component>
<!-- ... -->
Este sería el aspecto del componente anterior en MapForce:
En el fragmento de código, se definió <datapoint> como parámetro de entrada o salida de una función (o conector de entrada o salida). El argumento type de <datapoint> especifica el tipo de datos del parámetro (o el tipo de datos del valor devuelto).
Por cada función se permite un punto de datos de destino como máximo, pero no hay límite en el número de puntos de datos de origen que se pueden definir.
El tipo de datos de cada punto de datos debe ser un tipo XML Schema (p. ej. xs:string, xs:integer, etc.). Estos tipos de datos deben corresponder a los tipos de datos de los parámetros de la función que definió en la biblioteca Java, C++ o C#. Para ver la correspondencia entre tipos de datos XML Schema y de otros lenguajes consulte el apartado Correspondencias entre tipos de datos.
En la ventana Bibliotecas de MapForce las funciones van acompañadas de una descripción breve y una más larga. La descripción breve aparece siempre a la derecha del nombre de la función. La descripción más larga aparece cuando se pasa el puntero por encima de la descripción breve.
Paso 4. Definir implementaciones de lenguaje
Llegados a este punto debemos crear una conexión entre la función de la ventana Bibliotecas y la función de las clases Java, C# o C++ personales. Esto se consigue con el elemento <implementation>. Tal y como se explica más a arriba, las funciones pueden tener varios elementos <implementation>, uno por cada lenguaje de programación compatible. Una función se puede llamar Hello en Java o SayHello en C++. Por eso es necesario especificar un nombre de función distinto por cada lenguaje de programación. A continuación puede ver una función con tres implementaciones distintas:
<!-- ... -->
<component name="sayhello">
<!-- ... -->
<implementations>
<implementation language="cs">
<function name="HelloFunction"/>
</implementation>
<implementation language="java">
<function name="Hello"/>
</implementation>
<implementation language="cpp">
<function name="SayHello"/>
</implementation>
</implementations>
<!-- ... -->
</component>
<!-- ... -->
El valor que especifique como nombre de función debe ser idéntico al nombre del método de la clase Java, C# o C++.