VMware {code} Community
AdityaVishwanat
Contributor
Contributor

VIsdk with C++

I am planning to use a C++ client with the VISDk web service. Is this supported ? i did not see any examples for C++ anywhere . So awnted to check

0 Kudos
15 Replies
njain
Expert
Expert

VI API are Web services based APIs. You can use any programming or scripting language that provides utilities for generating client side stubs from the WSDL files. VI SDK provides samples for Java and C# (the SOAP toolkits are readily available for these). For C+, you can use gSOAP and create your applications. Even though the C+ ready-to-use samples are not shipped with SDK, but you will get all the help in the community here.

0 Kudos
AdityaVishwanat
Contributor
Contributor

Thanks naresh !

0 Kudos
stumpr
Virtuoso
Virtuoso

I've been doing work with gsoap and C++. There was some earlier work with C/gsoap (should find it with a forum search), but I found that C & gsoap required a lot of xml parsing and mangling to work well. I generally build a dynamic library with the VIM namespace and the derived functions from the wsdl files.

You can probably find some of the posts a few of us knocked around a while ago, if not, feel free to post up as you start working on it. Usually the first blocks people hit are dealing with SSL and compiling cookie support into gsoap.

Reuben Stump | http://www.virtuin.com | @ReubenStump
0 Kudos
AdityaVishwanat
Contributor
Contributor

Hey thanks stumpr, I have generated all the stub files for the VISDK WSDL. Can some tell me how do I start off. I need to make a simple login logut call. ?

0 Kudos
AdityaVishwanat
Contributor
Contributor

Hey Stumpr ,

Thanks for you reply. I have generated all the stubs for the VISDK WSDL. Can you tell me how to very if the infrastructure works . I need to make the simplest VISDK call to verify it .. maybe login /logout

0 Kudos
stumpr
Virtuoso
Virtuoso

Sure,

The easiest call is the AboutInfo object, which doesn't require a login. You can use this to determine the API type (HostAgent or VirtualCenter), version number, etc.

#include "soapVimBindingProxy.h"
#include "VimBinding.nsmap"
#include "soapH.h"
#include <time.h>
#include <iostream>
#include <typeinfo>

using namespace std;

void sigpipe_handle(int x) { cout << "sigpipe: " << x << endl; }

int main(int argc, char* argv[])
{
	VimBinding vim;
	ns1__ManagedObjectReference ManagedObjectRef;
	ns1__RetrieveServiceContentRequestType RetrieveServiceContentReq;
	_ns1__RetrieveServiceContentResponse RetrieveServiceContentRes;
	ns1__ServiceContent *ServiceContent;
	ns1__AboutInfo *AboutInfo;
	
	if (argc != 2)
	{
		cout << "Usage: " << argv[0] << " <service url>" << endl;
		exit(1);
	}
	
	string service_url(argv[1]);	
	
	vim.endpoint = service_url.c_str();
	soap_ssl_init();
	
	
	if (soap_ssl_client_context(
		vim.soap,
		SOAP_SSL_NO_AUTHENTICATION,
		NULL,
		NULL,
		NULL,
		NULL,
		NULL	))
	{
		cout << "SSL:";
		soap_print_fault(vim.soap, stderr);
		soap_done(vim.soap);
		soap_end(vim.soap);
		exit(1);
	}
	
	ManagedObjectRef.__item = "ServiceInstance";
	ManagedObjectRef.type = new string("ServiceInstance");
	RetrieveServiceContentReq._USCOREthis = &ManagedObjectRef;
	
	if ( vim.__ns1__RetrieveServiceContent(&RetrieveServiceContentReq, &RetrieveServiceContentRes) == SOAP_OK )
	{
		cout << "RetrieveServiceContent - OK" << endl;
	}
	else
	{
		delete ManagedObjectRef.type;
		soap_print_fault(vim.soap,stderr);
		soap_done(vim.soap);
		soap_end(vim.soap);
		exit(1);
	}
	
	ServiceContent = RetrieveServiceContentRes.returnval;
	
	if (ServiceContent && ServiceContent->about)
	{
		AboutInfo = ServiceContent->about;
		cout << "fullName: " << AboutInfo->fullName << endl;
		cout << "  name: " << AboutInfo->name << endl;
		cout << "  build: " << AboutInfo->build << endl;
		cout << "  version: " << AboutInfo->version << endl;
		cout << "  apiType: " << AboutInfo->apiType << endl;
		cout << "  productLineId: " << AboutInfo->productLineId << endl;
	}
	
	delete ManagedObjectRef.type;
	
	soap_done(vim.soap);
	soap_end(vim.soap);
	
	return 0;
	
}

Make sure you compile with --DWITH_OPENSSL & -DWITH_COOKIES. You'll need WITH_COOKIES once you start logging in and making subsequent calls that require credentials.

Reuben Stump | http://www.virtuin.com | @ReubenStump
0 Kudos
AdityaVishwanat
Contributor
Contributor

Hey Stumpr ,

Thanks so much . But what are these two files .

#include "soapVimBindingProxy.h"

#include "VimBinding.nsmap"

Are they generated files ?

0 Kudos
stumpr
Virtuoso
Virtuoso

Yes, assuming you're using gsoap and generated your headers from the VIM WSDL.

Assuming you're in a directory with the wsdl folder from the VI SDK and you have your gsoap directory in /usr/src:

/usr/src/gsoap-2.7/gsoap/bin/linux386/wsdl2h -o vim25.h -Iwsdl/vim25/ vim.wsdl

This will generate a header 'vim25.h'.

/usr/src/gsoap-2.7/gsoap/bin/linux386/soapcpp2 -x -C vim25.h -I/usr/src/gsoap-2.7/gsoap/import -d .

This will generate the files: soapStub.h, soapH.h, soapC.cpp, soapClient.cpp, soapClientLib.cpp, soapVimBindingProxy.h and VimBinding.nsmap

You'll have to create the object files for soapC.cpp, soapClient.cpp and stdsoap2.cpp. You'll have to link these object files into your program. I usually place these object files into a shared or static library and then just link against that library.

Reuben Stump | http://www.virtuin.com | @ReubenStump
0 Kudos
AdityaVishwanat
Contributor
Contributor

Ok I am not able to find the last three files. Is it possible that I generate only soapClientLib.cpp, soapVimBindingProxy.h and VimBinding.nsmap . Also why would I need these 3 files. Can I compile my program without these 3 files ?

0 Kudos
stumpr
Virtuoso
Virtuoso

Well, you will need soapVimBindingProxy.h and VimBinding.nsmap. These are the main includes you should use in a gsoap C++ program. They both call in soapH.h, which calls in soapStub.h. This then calls in stdsoap2.h.

So you will need soapVimBindingProxy.h, VimBinding.nsmap, soapH.h, soapStub.h, stdsoap2.h. You'll also need the import directory from the gsoap source for <vector> (called by soapStub.h ).

Are you using the gsoap toolkit? You should be getting all of these files. Post up the steps you used to generate your headers and stubs.

Reuben Stump | http://www.virtuin.com | @ReubenStump
0 Kudos
AdityaVishwanat
Contributor
Contributor

These are the files I have .

soapcpp2 stdsoap2.c stdsoap2.cpp stdsoap2.h wsdl2h

Also when I generated the stubs sometime back .Since I dont have the files that I mentioned I am now trying generate them again

Here is the error I get when I try to run wsdl2h

./wsdl2h: error while loading shared libraries: libstdc++.so.6: cannot open shared object file: No such file or directory

0 Kudos
stumpr
Virtuoso
Virtuoso

You have to check your environment. Your libstdc++ would normally be in /usr/lib. You might have an older version or not have it installed.

If you have it, check the path and rerun ldconfig.

Reuben Stump | http://www.virtuin.com | @ReubenStump
0 Kudos
AdityaVishwanat
Contributor
Contributor

Hello Folks

I am getting these compilation errors when I try to create a simple login program (attached).The first set errors seem compiler related. The other seems to be VISDK related. Can you help me out ?

-bash-3.2$ g++ Login.cpp -DWITH_OPENSSL -DWITH_COOKIES

In file included from /usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.1i/../../../../include/g++-3/iostream.h:31,

from Login.cpp:1:

/usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.1i/../../../../include/g++-3/streambuf.h: In method `struct streampos streambuf::pubseekoff(long long int, ios::seek_dir, int = 3)':

/usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.1i/../../../../include/g++-3/streambuf.h:362: conversion from `__off64_t' to non-scalar type `streampos' requested

/usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.1i/../../../../include/g++-3/streambuf.h: In method `struct streampos streambuf::pubseekpos(_G_fpos64_t, int = 3)':

/usr/local/lib/gcc-lib/i686-pc-linux-gnu/2.95.1i/../../../../include/g++-3/streambuf.h:364: `struct streampos' used where a `long long int' was expected

Login.cpp: In function `int main(int, char *)':

Login.cpp:10: aggregate `struct ns1_RetrieveServiceContent SvcCont' has incomplete type and cannot be initialized

Login.cpp:14: aggregate `struct ns1_Login login' has incomplete type and cannot be initialized

Login.cpp:17: confused by earlier errors, bailing out

0 Kudos
sg072019
Contributor
Contributor

Hi..I am not able to generate "soapVimBindingProxy.h" with

soapcpp2 -i -C -I\C:\Usr\gsoap\import vimService.h

Can you please tell how to resolve this?

0 Kudos
Shempp
Contributor
Contributor

Hi, you wrote the command wrong. In your case, the correct command will look like this: soapcpp2 -i -C -I C:\Usr\gsoap\import -d <path_to_generated_sources> vimService.h
For example: soapcpp2 -i -C -I C:\Usr\gsoap\import -d C:\vim25 vimService.h

0 Kudos