Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations SkipVought on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

VARIANT

Status
Not open for further replies.

Themuppeteer

Programmer
Apr 4, 2001
449
0
0
BE
I have a struct

myClass
{
char* myString;
int myIntArray[20];
char* myOtherString;
}

All the values have been filled in, (on server side) and by using com it has arrived in my client in this variable:

variant result;


Can someone provide me with the code to get all the values (myString,myIntArray and myOtherString) out of the result var ?

I'd appreciate it.

(I already asked something similar but wasnt specific enough I think)

Thnx a lot. Greetz,
muppeteer.gif

NOSPAM_themuppeteer@hotmail.com (for mails, remove the NOSPAM_)

Don't eat yellow snow...and don't mess with your fstab!
 
how are you getting the result?
Have you tried casting the
result.parray
to a pointer to a structure of your type? [red]Nosferatu[/red]
We are what we eat...
There's no such thing as free meal...
once stated: methane@personal.ro
 
? I get the result as a return value of my (webservice) call. The server returns an object. In visual studio.net I see that it returns it correctely (as it is rather simple there),but I also have to be able to do it in VC++.
Do I have to make the struct to in my client and then try to cast the result var to it? What is result.parray? Greetz,
muppeteer.gif


NOSPAM_themuppeteer@hotmail.com (for mails, remove the NOSPAM_)

"Those who say they understand chess, understand nothing"

-- Robert HUBNER
 
Look at the VARIANT datatype in MSDN.
It is a structure containing a huge union of members that represent pointers to different things.
parray is of type VT_ARRAY, which means a sequence of bytes; I'd take these bytes and convert them to what I need (myClass, for instance).
[red]Nosferatu[/red]
We are what we eat...
There's no such thing as free meal...
once stated: methane@personal.ro
 
Ok, this comes staight out of the code...

class Object
{
public:
char* name;
int tel;
int cnt;
char* anotherString;
int myIntArray[5];

};

This is the actual object. I made the class on my clientside to so that I can do the cast like you said.

then:
Object *myResult=(Object*)(result.parray);
printf(myResult->anotherString);


and I get an unhandled exception:access violation
(but it compiles)

Do I miss something obvious ? Greetz,
muppeteer.gif


NOSPAM_themuppeteer@hotmail.com (for mails, remove the NOSPAM_)

"Those who say they understand chess, understand nothing"

-- Robert HUBNER
 
OK. So it is a little more complicated that I thought.
You were initially talking about structures and then about objects. It it was a structure, then the server chould have just filled up a BLOB or something and send it to you (that's what my understanding).

If you want an instance of an object that was created on some server, you are getting deep into COM, so I'd suggest reading some msdn'ish. Try looking the mSDN for
"The Component Object Model: A Technical Overview".
[red]Nosferatu[/red]
We are what we eat...
There's no such thing as free meal...
once stated: methane@personal.ro
 
If I change the Class to struct and remove the public it still doesn't work. If I would know how to do this with structs, it would be a great help to already. Greetz,
muppeteer.gif


NOSPAM_themuppeteer@hotmail.com (for mails, remove the NOSPAM_)

"Those who say they understand chess, understand nothing"

-- Robert HUBNER
 
well... are you sure that you are getting anything in that variant? Can't you debug it step by step?
How is the object (structure) filled in in the first place (on the server side)?
[red]Nosferatu[/red]
We are what we eat...
There's no such thing as free meal...
once stated: methane@personal.ro
 
I'm sure the variant is not empty,I checked it with a dot net client.
I've got it to work in VC++ with only a string in it, then I could extract the string

_variant_t result1;
result1.Attach(result);

_bstr_t result2;
result2 = _bstr_t(result1);

printf((char*)result2);
printf("\n");

And that worked.

Now I have to send structs instead of strings.
Meanwhile I changed the return type of the server to struct but no succes...
Greetz,
muppeteer.gif


NOSPAM_themuppeteer@hotmail.com (for mails, remove the NOSPAM_)

"Those who say they understand chess, understand nothing"

-- Robert HUBNER
 
Hi Themuppeteer,
I gave a look to your program and i feel that you are required to use safearray as mandatory at a later stage...I am giving you the sample code which is acting as both server and client...
Hope it helps.....
#include "stdafx.h"
#include <windows.h>
#include <comdef.h>
#include <stdio.h>

class MyInClass
{
public:
char* myString;
int myInt;
char* myOtherString;
};

class MyOutClass
{
public:
char* myString;
int myInt;
char* myOtherString;
};

int main(int argc, char* argv[])
{
//Now filling these values as might have been stored in server
_bstr_t bstrData;
MyInClass myicls;
MyOutClass myocls;

myicls.myString = &quot;Pankaj&quot;;
myicls.myInt= 3;
myicls.myOtherString = &quot;Other&quot;;

//Filling in Variant
VARIANT var,var1;//One will not be able to hold both so have taken 2..better use safearray later
wchar_t *pw;
pw= new wchar_t[32];

mbstowcs(pw,myicls.myString,8 );
bstrData=pw;
var.vt=VT_BSTR;
var.bstrVal =bstrData;

var1.vt=VT_I2;
var1.intVal=myicls.myInt;


//Now getiing values back...we can assume that this is client side
char *pOutChar;
pOutChar = new char[32];
pw = var.bstrVal;

wcstombs(pOutChar,pw,8);
myocls.myString =pOutChar;//Filling back in Out Class

myocls.myInt = var1.intVal;


//Printing both
char szTestVals[32];
int iTmpVal;
iTmpVal=sprintf(szTestVals,&quot;%s &quot;,myocls.myString);
iTmpVal+=sprintf(szTestVals + iTmpVal,&quot;%d&quot;,myocls.myInt);
MessageBox(0,szTestVals,&quot;&quot;,0);


return 0;
}

 
That's because it's a BSTR and COM knows how to marshall that stuff. COM does not know anything about your struct however. You need to do as nosferatu says; with an array. Only your struct contains character pointers. They point to memory on the server machine. You can't use this pointer on the client to read from the server memory. You'll have to send in the memory block they are pointing to.
Greetings,
Rick
 
For the communication between client and server I use mssoap,server runs on linux with gsoap.
what do you mean with: &quot;You'll have to send in the memory block they are pointing to. &quot;, when I'm talking string, I'm automatically talking pointer to character.
Greetz,
muppeteer.gif


NOSPAM_themuppeteer@hotmail.com (for mails, remove the NOSPAM_)

&quot;Those who say they understand chess, understand nothing&quot;

-- Robert HUBNER
 
if I do a
cout<<result.parray<<endl;

I get
0xCCCCCCCC

Greetz,
muppeteer.gif


NOSPAM_themuppeteer@hotmail.com (for mails, remove the NOSPAM_)

&quot;Those who say they understand chess, understand nothing&quot;

-- Robert HUBNER
 
Hello pankajkumar ,

after taking a closer look at your sample,I've noticed
you don't get your second string out of the variant. I'm pretty sure the complete struct should be in the variant variable 'result'. How do you get the second one out? Can a variant only contain 1 variable of the type int and 1 of char etc... ?
thnx Greetz,
muppeteer.gif


NOSPAM_themuppeteer@hotmail.com (for mails, remove the NOSPAM_)

&quot;Those who say they understand chess, understand nothing&quot;

-- Robert HUBNER
 
Hello Themuppeteer,
I gave it this a look again , I think that whatever your goal is can also be done easily..
In this approach i tried to avoid usage of SafeArray(sometimes i don't like its usage while other ways are there)..give it a look..only one variable array is enough

#include <windows.h>
#include <comdef.h>
#include <stdio.h>

class MyInClass
{
public:
char* myString;
int myInt;
char* myOtherString;
};

class MyOutClass
{
public:
char* myString;
int myInt;
char* myOtherString;
};

//Which will display out clas
void MyOutFunction(variant_t var[2],wchar_t *pw,wchar_t*pw1);

int main(int argc, char* argv[])
{
//Now filling these values as might have been stored in server
_bstr_t bstrData,bstrData1;
MyInClass myicls;
//MyOutClass myocls;

myicls.myString = &quot;Pankaj&quot;;
myicls.myInt= 3;
myicls.myOtherString = &quot;Other&quot;;

//Filling in Variant
variant_t var[2];//One will not be able to hold both so have taken 2..better use safearray as an alternate
wchar_t *pw,*pw1;
pw= new wchar_t[32];

mbstowcs(pw,myicls.myString,8 );
bstrData=pw;
var[0].vt=VT_BSTR;
var[0].bstrVal =bstrData;


var[1].vt=VT_BSTR;
pw1= new wchar_t[32];

mbstowcs(pw1,myicls.myOtherString,8 );
bstrData1=pw1;
var[1].bstrVal=bstrData1;

var[2].vt=VT_I2;
var[2].intVal=myicls.myInt;

//Calling function which will output the data
MyOutFunction(var,pw,pw1);

return 0;
}

void MyOutFunction(variant_t var[2],wchar_t *pw,wchar_t*pw1)
{
//Now getiing values back...we can assume that this is client side..data is held by var
MyOutClass myocls;
char *pOutChar,*pOutChar1;
pOutChar = new char[32];
pOutChar1 = new char[32];

pw = var[0].bstrVal;
pw1 = var[1].bstrVal;

wcstombs(pOutChar,pw,8);
myocls.myString =pOutChar;//Filling back in Out Class

wcstombs(pOutChar1,pw1,8);
myocls.myOtherString =pOutChar1;//Filling back in Out Class


myocls.myInt = var[2].intVal;

//Printing both
char szTestVals[32];
int iTmpVal;
iTmpVal=sprintf(szTestVals,&quot;%s &quot;,myocls.myString);
iTmpVal+=sprintf(szTestVals + iTmpVal,&quot;%s&quot;,myocls.myOtherString);
iTmpVal+=sprintf(szTestVals + iTmpVal,&quot;%d&quot;,myocls.myInt);
MessageBox(0,szTestVals,&quot;&quot;,0);
}
 
I see you declaring two variant_t wrappers:

variant_t var[2];//One will not be able to hold both so have taken 2..better use safearray as an alternate

But you're using three:

var[0].bstrVal =bstrData;
var[1].bstrVal =bstrData1;
var[2].intVal=myicls.myInt;


This will crash.


Furthermore; wy sending the VT_BSTR variants as well as the character pointers?

Greetings,
Rick
 
1.ok this line &quot;var[2].intVal=myicls.myInt;&quot;
used because on variant was getting able to hold only one value due to vt member at a time
2.I took character pointer as well as BSTR because in class this is a char pointer data and in varaint this thing is getting wrapped in a variant variable to send output(which goes to some other class)..
so used so
If you have any better idea about this code you can post your answer with example
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top