[lnkForumImage]
TotalShareware - Download Free Software

Confronta i prezzi di migliaia di prodotti.
Asp Forum
 Home | Login | Register | Search 


 

Forums >

microsoft.public.dotnet.framework.interop

Returning an Array of C# Structures

hpw

6/14/2007 1:42:00 PM

Hi all,

i'm trying to use COM Interop to return an array of c# structures to
Native code.
I tried to marshall the Array as SAFEARRAY.

The structure:

[StructLayout(LayoutKind.Sequential)]
[ComVisible(true)]
public struct teststruct{
[MarshalAs(UnmanagedType.LPStr)]
public string string1;

[MarshalAs(UnmanagedType.LPStr)]
public string string2;

[MarshalAs(UnmanagedType.LPStr)]
public string string3;

[MarshalAs(UnmanagedType.SafeArray)]
public string[] parameters;

};

is given back via a function

[return: MarshalAs(UnmanagedType.SafeArray)]
public teststruct[]
GetTestStruct([MarshalAs(UnmanagedType.LPStr)]string strParam, int
iParam) ;

I've generated the TLB via tlbexp.exe and used the Objects in a C++
Program.

Other calls with string-arrays and int-arrays work find. But for this
particular case i get the following _com_error:
0x80028019 - Old format or invalid type library

I also tried to specifiy the SafeArraySubType.
No Effect.

Any Help would be appreciated

HPW

4 Answers

herc

6/14/2007 3:53:00 PM

0

On Jun 14, 9:41 am, hpw <h...@hp-weidinger.at> wrote:

> i'm trying to use COM Interop to return an array of c# structures to
> Native code. I tried to marshall the Array as SAFEARRAY.

Question: Does it HAVE to be an array or can you return a
collection?

Personally, I HATE passing arrays (SAFEARRAYS) around in COM, they are
a real pain. If a collection is an option, look into the IEnumVARIANT
interface. I would susspect that a C# ICollection interface is a
IEnumVARIANT. Google it and I think you will find much easier ways of
dealing with this issue;)

Cartoper

hpw

6/14/2007 4:14:00 PM

0

> > i'm trying to use COM Interop to return an array of c# structures to
> > Native code. I tried to marshall the Array as SAFEARRAY.
>
> Question: Does it HAVE to be an array or can you return a
> collection?
>
> Personally, I HATE passing arrays (SAFEARRAYS) around in COM, they are
> a real pain. If a collection is an option, look into the IEnumVARIANT
> interface. I would susspect that a C# ICollection interface is a
> IEnumVARIANT. Google it and I think you will find much easier ways of
> dealing with this issue;)

Hi Cartoper,

thanks for your comments.

At the moment i did a similar workaround even though i do not like it:
i implemented an object with a dual-interface that allows me to read
the entires of the array.
I can pass back a reference to this Helper-Object that i can use to
read the structs.

If i pass back those things as Array (wich implements the ICollection
and IList interface) i get
an mscorlib::_Array that i can use. Unfortunately reading the items
using the IList interface always gives
me an Error "invalid argument type" if i try to read the arrays as
VARIANTs.

I havent tried using an IEnumVARIANT yet but i will also try this.

br
HPW

SteveR

7/9/2007 6:52:00 AM

0

This is exactly the same problem I'm having. Have you got any code samples
you could post or url's I can refer to?
--
Steve


"herc" wrote:

> On Jun 14, 9:41 am, hpw <h...@hp-weidinger.at> wrote:
>
> > i'm trying to use COM Interop to return an array of c# structures to
> > Native code. I tried to marshall the Array as SAFEARRAY.
>
> Question: Does it HAVE to be an array or can you return a
> collection?
>
> Personally, I HATE passing arrays (SAFEARRAYS) around in COM, they are
> a real pain. If a collection is an option, look into the IEnumVARIANT
> interface. I would susspect that a C# ICollection interface is a
> IEnumVARIANT. Google it and I think you will find much easier ways of
> dealing with this issue;)
>
> Cartoper
>
>

hpw

7/25/2007 11:50:00 AM

0

Hi Steve,

sorry for the late answer.

I couldn't solve the problem - so i found a workaround for this.
I've used a wrapper for the list and returned this instead of the
array.

Alternatively you can also use one of the list-Classes provided by
System.Collections. ...

here is what i did:

[Guid("xxxxxxxxxxxxxxx")]
[ComVisible(true)]
[InterfaceType(ComInterfaceType.InterfaceIsDual)]
public interface ITeststructCollection {
void add(teststruct c);
int count();
teststruct get([MarshalAs(UnmanagedType.I4)] int i);
void Dispose();
};

and the implementation for this (TeststructCollection).
the call which returns the Interface looks like

TeststructCollection
GetCallEntries([MarshalAs(UnmanagedType.LPStr)]string smthing, int i);

Native code looks like this

....
_CallEntryCollectionPtr entries=engine-
>GetCallEntries(pszSmthing,i);

CoTaskMemFree(pszSmthing);

ICallEntryCollection *coll;
hResult=entries->QueryInterface(&coll);

if (FAILED(hResult)) {
char ch[255];
::FormatMessage(FORMAT_MESSAGE_FROM_SYSTEM,NULL,hResult,NULL,ch,
255,NULL);
char pszErr[1024];
sprintf(pszErr,"Reading COM-Entries Error: 0x%08x - %s
\n",hResult,ch);
fprintf(stderr,pszErr);
return ;
}

int count=coll->count();
....


hope this helps.

br
HPW

On Jul 9, 8:52 am, SteveR <Ste...@discussions.microsoft.com> wrote:
> This is exactly the same problem I'm having. Have you got any code samples
> you could post or url's I can refer to?
> --
> Steve
>
> "herc" wrote:
> > On Jun 14, 9:41 am, hpw <h...@hp-weidinger.at> wrote:
>
> > > i'm trying to use COM Interop to return an array of c# structures to
> > > Native code. I tried to marshall the Array as SAFEARRAY.
>
> > Question: Does it HAVE to be an array or can you return a
> > collection?
>
> > Personally, I HATE passing arrays (SAFEARRAYS) around in COM, they are
> > a real pain. If a collection is an option, look into the IEnumVARIANT
> > interface. I would susspect that a C# ICollection interface is a
> > IEnumVARIANT. Google it and I think you will find much easier ways of
> > dealing with this issue;)
>
> > Cartoper