Home | Contact Us | FAQ | Search & Site Map | Link to Us
Sign In | Join | Other 45 Sites in Network
HomeAnnouncementsFree MagazinesWhite PapersSubmit Content
Discussion GroupsASP.NETWindows FormsLanguages.NET FrameworkVisual Studio.NET
Articles.NET FrameworkASP.NETToolsWindows Forms
.NET DirectoryOpen Source ProjectsUser GroupsWeb Resources
Related Topics
Visual Basic 6SQL ServerMS AccessOther DB ProductsMS Server ProductsMore Topics ...

.NET Forum / .NET Framework / Interop / July 2007

Tip: Looking for answers? Try searching our database.

Returning an Array of C# Structures

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
hpw - 14 Jun 2007 14:41 GMT
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
herc - 14 Jun 2007 16:53 GMT
> 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 - 14 Jun 2007 17:14 GMT
> > 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.
[quoted text clipped - 7 lines]
> 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 - 09 Jul 2007 07:52 GMT
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?
Signature

Steve

> > 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.
[quoted text clipped - 9 lines]
>
> Cartoper
hpw - 25 Jul 2007 12:50 GMT
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

> 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?
[quoted text clipped - 14 lines]
>
> > Cartoper

Rate this thread:







Free Magazines

Get these publications absolutely FREE for up to 12 months. There are no hidden fees and no obligation. Simply choose a title, complete the application form and submit it. Read more ...

Oracle MagazineNetwork ComputingComputer WorldBio-IT WorldeWeekInformation WeekInfosecurity
 
Sign In
Join
My Latest Posts
My Monitored Threads
My Blog
My Photo Gallery
My Profile
My Homepage

Start New Thread
Enable EMail Alerts
Rate this Thread



©2008 Advenet LLC   Privacy Policy - Terms of Use
This website includes both content owned or controlled by Advenet as well as content owned or controlled by third parties.