¿Cómo llamar a servicios web desde C/C++?

Como últimamente me han realizado esta pregunta en varias ocasiones la voy a contestar en este post, seguro que a alguien le vendrá bien la respuesta.

Los servicios web se han extendido espectacularmente en los últimos años. Ya casi no existe ninguna aplicación que no exponga un API de integración basada en una fachada de servicios web. Una de las grandes ventajas de los servicios web es que se pueden llamar desde cualquier lenguaje de programación ya que lo único necesario es ser capaz de contruir un mensaje SOAP (que no es más que una cadena de texto) y poder realizar un POST (que en esencia es enviar datos por un socket). Aunque desde cualquier lenguaje se pueden realizar estas tareas a menudo es necesario utilizar un proxy de lado cliente que nos abstraiga de la dificultades de componer el mensaje SOAP y realizar el POST.

En C++ contamos con numerosas posibilidades a la hora de llamar a servicios web, aunque ninguna es evidente a primera vista.

En Visual Studio, formando parte parte de ATL Server contamos con una herramienta poco conocida, llamada sproxy, que es capaz de generarnos el proxy necesario para invocar a un servicio web a partir del WSDL del servicio. Sproxy genera un archivo .h que contiene las clases necesarias para llamar al servicio web. Sproxy tiene dos pegas: es una solución que solo funciona con el compilador de Microsoft y que depende de MSXML (tendremos que distribuirlo con nuestra aplicación) y de las librerias de ATL (por lo tanto no se puede compilar en la versión Express de Visual C++).

Otra opción es utilizar el Microsoft SOAP Toolkit, que aun se puede descargar pero que no ya no tiene soporte por parte de Microsoft.  Salvo que se trate de mejorar una aplicación que ya usa este toolkit es casi mejor olvidar esta opción.

En Visual C++, contamos con la opción de utilizar C++/CLI y toda la potencia de las clases del framework de .Net para llamar a los servicios web. Dada la posibilidad de mezclar código manejado y código no manejado en aplicación este puede ser el camino más sencillo siempre que no nos importe exigir que el framework de .net esté instalado en la máquina cliente.  Es la aproximación más sencilla pues solo es necesario agregar una referencia al servicio web para que se genere el proxy manejado necesario para llamar al servicio. El proceso es exactamente el mismo que cuando llamamos a un servicio web desde C#.

Por último, existe otra opción que tiene como principales ventajas que es mutiplataforma y que funciona con cualquier compilador de C o C++. Se trata de gSOAP, un proyecto libre que proporciona las herramientas necesarias para generar el proxy que nos permita llamar a un servicio web desde casi cualquier plataforma usando C o C++. No es tan facil de usar como las anteriores opciones pero funciona muy bien. Si la necesidad de usar Linux, Windows, Windows CE o Mac como cliente del servico es clave, gSoap es la elección clara. En la web de la herramienta hay documentación más que suficiente sobre como utilizar esta herramienta. Yo la he usado recientemente con bastante exito para llamar a un servicio de integración que expone una aplicación en la que estado trabajando los ultimos años. Os dejo un poco de ese código, para que veaís que una vez generardo el proxy la llamada es más o menos sencilla:

/Incluimos los archivos generados por gSOAP

//http://www.cs.fsu.edu/~engelen/soap.html

//que nos generan las clases proxy necesaria para llamar a servicio web

//Para que los proxys compilen correctamente, es necesario incluir en la

//compilación los archivos soapC.cpp, soapClient.cpp y stdsoap2.cpp

//además de las cabeceras necesarias, generadas por gSOAP

#include «soapproxy/soapSaveDataSoapProxy.h»

#include «soapproxy/savedatasoap.nsmap»

 

//Url en la que se encuenta el servicio de Prisma 3

//Es necesario establecerla correctamente al servidor concreto

const char endpoint[] = http://servidorprisma/prismaweb/webservices/public/savedata.asmx;

 

//Función que pemite llamar al servicio de carga de datosde Prisma 3

string SaveTableData(string& user, string& company, string& tableDataNode)

{

    //Proxy SOAP generado con gSOAP

    SaveDataSoap p;

    p.endpoint = endpoint;

 

    //Clase del proxy que contiene los parametros del servicio

    _ns1__SaveTableData2 params;

 

    params.user = &user;

    params.company = &company;

    params.tableDataNode = &tableDataNode;

 

    //Clase del proxy que contiene la respuesta del servicio

    _ns1__SaveTableData2Response response;

 

    //Llamada al servicio

    p.__ns1__SaveTableData2(&params, &response);

 

    return *response.SaveTableData2Result;

}

Cabe reseñar que cuanto más simples y comunes sean los tipos que toman como parámetros los servicios web, más facil nos será llamarlos desde múltiples lenguajes o plataformas. Cualquier lenguaje sabe lo que es un string, pero solo los lenguajes .Net saben lo que es un Dataset.

Resaltar tambien que gSoap, permite generar el esqueleto de la parte servidora de un servicio web, algo muy util si necesitamos exponer servicios web desde C/C++. Pero de todos modos, en plataforma windows, para exponer servicios web desde Visual C++ es mucho más simple y potente usar ATL Server.

Da gusto ver que el C/C++ es como andar en bicicleta, una vez bien aprendido no se olvida y resulta útil cuando uno menos lo espera…

5 comentarios sobre “¿Cómo llamar a servicios web desde C/C++?”

  1. gSoap qué requisitos de despliegue tiene? sproxy te obliga a distribuir el MSXML, gSOAP tiene alguna dependencia de este estilo? Distribuir algún parser XML? ( libxml2, tinyXML….)

    Ibon.

  2. Ningún requisito… todo lo necesario lo incluye en los ficheros de código que genera (soapC.cpp, soapClient.cpp) y un archivo de código que proporciona gSoap (stdsoap2.cpp). Cero dependencias, es otra de las grandes ventajas de gSOAP.

  3. Disculpa hermano. Estoy tratando de usar estas librerias pero tengo problemas.. nose si entendi bien lo que dice el manual..
    el manual dice: «To complete the build, compile and link the generated soapC.cpp, soapcalcProxy.cpp, and the run-time
    gSOAP engine stdsoap2.cpp with your code.»

    Lo que entiendo de esto es que:
    Para completar el programa hay que compilar y enlazar los archivos soapC.cpp, soapcalc.Proxy.cpp y stdsoap2.cpp con el codigo. La verdad estoy dando bastante tumbo con esto pero hasta ahora nose como hacerlo.. si me podrias ayudar te agradeceria.
    Saludos
    PD: Mi correo es francofloresdelgado@hotmail.com

  4. Hola gracias por responder. Disculpa por no responder antes, me fue imposible.

    Este es el pequeño codigo de prueba que estoy tratando de compilar

    #include
    #include
    #include «soapcalcProxy.h»
    #include «calc.nsmap»

    using namespace std;

    int main(int argc, char *argv[])
    {
    calcProxy service;
    system(«PAUSE»);
    return EXIT_SUCCESS;
    }

    Y estos son los errores que me lanza:

    [Linker error] undefined reference to `calcProxy::calcProxy()’

    [Linker error] undefined reference to `calcProxy::~calcProxy()’

    [Linker error] undefined reference to `calcProxy::~calcProxy()’

    ld returned 1 exit status

    C:Documents and SettingsAdministradorMis documentosProyectos C++PruebaSoapMakefile.win [Build Error] [PruebaSoap.exe] Error 1.

    Ese es el error que me lanza. Yo uso el Dev-C++ aunque tambien tengo instalado el visual estudio 2005.

    Espero que me puedas ayudar. Gracias!! Saludos

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *