Fixed-size arrays as event args in managed code 
Author Message
 Fixed-size arrays as event args in managed code

Does anyone know what this error message means exactly, and how to get
around it?

    Structure <array type> cannot be indexed because it
    has no default property

I'm porting a VC++6 ActiveX control to a managed class in VC++7.

The control/class is an I/O wrapper around a custom hardware driver;
it reads data packets from my driver, sorts them according to type and
passes them to the overlying app in events.  To make access in the app
more readable and get some help from intellisense, they are being
passed as structures.

The packets, as implemented in the VC++6 header and idl file, look
somewhat like this (simplified and anonymized):

        typedef struct tagCR7_DATA {
                BYTE b1;
                BYTE b2;
                BYTE ba1[4];
                BYTE ba2[4];
                BYTE b3;
                BYTE b4;
        } CR7DATA, *PCR7DATA;

with event:

        [id(23)] void CR7(PCR7DATA Data);

In VC++7, I declared the structures as "public __value struct ...".

The problem is that I can't pass the array members.

If I make them dynamic (__gc), there can only be a pointer in the
structure where the array used to be, and the incoming data won't map
1-on-1 to the structure anymore.

If I make them __nogc[4] I suppose the elements will be stored in the
structure as intended, but trying to retrieve a value from one of the
arrays in a VB7 app results in this error:

    Structure $ArrayType$0xc4130462 cannot be indexed because it
    has no default property

Is there a way to get around this (i.e., to pass fixed-size static
arrays inside a structure)?



Sun, 11 Sep 2005 18:24:33 GMT  
 Fixed-size arrays as event args in managed code

--------------------

Quote:

> Subject: Fixed-size arrays as event args in managed code
> Date: Wed, 26 Mar 2003 11:24:33 +0100
> Does anyone know what this error message means exactly, and how to get
> around it?

>     Structure <array type> cannot be indexed because it
>     has no default property

> I'm porting a VC++6 ActiveX control to a managed class in VC++7.

> The control/class is an I/O wrapper around a custom hardware driver;
> it reads data packets from my driver, sorts them according to type and
> passes them to the overlying app in events.  To make access in the app
> more readable and get some help from intellisense, they are being
> passed as structures.

> The packets, as implemented in the VC++6 header and idl file, look
> somewhat like this (simplified and anonymized):

>    typedef struct tagCR7_DATA {
>            BYTE b1;
>            BYTE b2;
>            BYTE ba1[4];
>            BYTE ba2[4];
>            BYTE b3;
>            BYTE b4;
>    } CR7DATA, *PCR7DATA;

> with event:

>    [id(23)] void CR7(PCR7DATA Data);

> In VC++7, I declared the structures as "public __value struct ...".

> The problem is that I can't pass the array members.

> If I make them dynamic (__gc), there can only be a pointer in the
> structure where the array used to be, and the incoming data won't map
> 1-on-1 to the structure anymore.

> If I make them __nogc[4] I suppose the elements will be stored in the
> structure as intended, but trying to retrieve a value from one of the
> arrays in a VB7 app results in this error:

>     Structure $ArrayType$0xc4130462 cannot be indexed because it
>     has no default property

> Is there a way to get around this (i.e., to pass fixed-size static
> arrays inside a structure)?

You have to attach  StructLayout attribute (defined in
System::Runtime::InteropServices namespace)  to your valuetype and also
attach MarshalAs attribute (also defined in the same namespace) on your
array members (ba1 and ba2).

use
[ StructLayout( LayoutKind.Sequential )]
before your valuetype definition

use
 [ MarshalAs( UnmanagedType::ByValArray, SizeConst=4 )]
before your array member definition.

Try these and let us know if it helps.

You can get general information on interop on msdn (MSDN Home >  MSDN
Library >  .NET Development >  .NET Framework SDK >  Product Documentation

Quote:
>  Programming with the .NET Framework >  Interoperating with Unmanaged

Code >  Interop Marshaling )

--
Siva Challa, Microsoft Visual C++ Team
This posting is provided "AS IS" with no warranties, and confers no rights.
Use of included script samples are subject to the terms specified at
http://www.microsoft.com/info/cpyright.htm



Tue, 20 Sep 2005 03:20:20 GMT  
 Fixed-size arrays as event args in managed code

Quote:

> You have to attach  StructLayout attribute (defined in
> System::Runtime::InteropServices namespace)  to your valuetype and also
> attach MarshalAs attribute (also defined in the same namespace) on your
> array members (ba1 and ba2).

> use
> [ StructLayout( LayoutKind.Sequential )]
> before your valuetype definition

> use
>  [ MarshalAs( UnmanagedType::ByValArray, SizeConst=4 )]
> before your array member definition.

> Try these and let us know if it helps.

Thanks.

I'm currently working on something else with higher priority, but I'll
try it as soon as I can.



Tue, 20 Sep 2005 19:20:04 GMT  
 Fixed-size arrays as event args in managed code

Quote:

> Try these and let us know if it helps.

I put my other work aside for a moment and quickly tried it on one
type.

I had to remove the "LayoutKind." from "LayoutKind.Sequential" or it
wouldn't compile:

        d:\Grumium\ParComm\ParComm.h(282): error C2363: cannot
        evaluate argument 'LayoutKind.Sequential' of custom attribute
        'System::Runtime::InteropServices::StructLayoutAttribute'

After that it compiled, but I still get the same error in VB7:

        Structure '$ArrayType$0xc4130472' cannot be indexed because it
        has no default property.

Additional question: I suppose it's safest to add "Pack=1" to be sure
no members get realigned to an 8-byte boundary, even though it looks
like everything comes through OK so far (if I use individual byte
members instead of arrays)?

        [StructLayout(Sequential, Pack=1)]

The version I tried looks like this (reformatted to avoid wrapping).

[StructLayout(Sequential)] public __value struct CRAZY_7_DATA {
  Byte TriGameStat;
  Byte OutGame;
  Byte GameStat;
  Byte Val;
  Byte Tilt;
  Byte ExtraBallStat;
  Byte Select;
  Byte ModeRnd;
  [MarshalAs(UnmanagedType::ByValArray, SizeConst=4)]
     Byte Hole __nogc [4];
  [MarshalAs(UnmanagedType::ByValArray, SizeConst=4)]
     Byte HoleBitmap __nogc [4];
  [MarshalAs(UnmanagedType::ByValArray, SizeConst=3)]
     Byte Wheel __nogc [3];
  Byte ScoreTable;
  Int32 Score;
  Byte NumberPlayed;

Quote:
};

I also tried with 'Pack = 1', but (as I expected) it didn't make any
difference.


Tue, 20 Sep 2005 20:39:58 GMT  
 Fixed-size arrays as event args in managed code
LayoutKind::Sequential was the proper form, Siva made a typo in his post.
Can't immediately help you with the core issue.

Ronald


Quote:


> > Try these and let us know if it helps.

> I put my other work aside for a moment and quickly tried it on one
> type.

> I had to remove the "LayoutKind." from "LayoutKind.Sequential" or it
> wouldn't compile:

> d:\Grumium\ParComm\ParComm.h(282): error C2363: cannot
> evaluate argument 'LayoutKind.Sequential' of custom attribute
> 'System::Runtime::InteropServices::StructLayoutAttribute'

> After that it compiled, but I still get the same error in VB7:

> Structure '$ArrayType$0xc4130472' cannot be indexed because it
> has no default property.

> Additional question: I suppose it's safest to add "Pack=1" to be sure
> no members get realigned to an 8-byte boundary, even though it looks
> like everything comes through OK so far (if I use individual byte
> members instead of arrays)?

> [StructLayout(Sequential, Pack=1)]

> The version I tried looks like this (reformatted to avoid wrapping).

> [StructLayout(Sequential)] public __value struct CRAZY_7_DATA {
>   Byte TriGameStat;
>   Byte OutGame;
>   Byte GameStat;
>   Byte Val;
>   Byte Tilt;
>   Byte ExtraBallStat;
>   Byte Select;
>   Byte ModeRnd;
>   [MarshalAs(UnmanagedType::ByValArray, SizeConst=4)]
>      Byte Hole __nogc [4];
>   [MarshalAs(UnmanagedType::ByValArray, SizeConst=4)]
>      Byte HoleBitmap __nogc [4];
>   [MarshalAs(UnmanagedType::ByValArray, SizeConst=3)]
>      Byte Wheel __nogc [3];
>   Byte ScoreTable;
>   Int32 Score;
>   Byte NumberPlayed;
> };

> I also tried with 'Pack = 1', but (as I expected) it didn't make any
> difference.



Sat, 24 Sep 2005 03:02:20 GMT  
 Fixed-size arrays as event args in managed code
On Mon, 7 Apr 2003 12:02:20 -0700, "Ronald Laeremans [MSFT]"

Quote:

> LayoutKind::Sequential was the proper form, Siva made a typo in his post.

Thanks, I should have seen that myself.

Quote:
> Can't immediately help you with the core issue.

In that regard, I may have run onto a bug.

In VB.Net you can declare an array with explicit bounds inside a
structure, if you apply a VB-specific attribute "VBFixcedArray" to it,
as in

Public Structure MyStructure
    <VBFixedArray(6)> Dim MyArray() As Integer
End Structure

I wanted to try if the C++ compiler would accept the VBFixedArray
attribute in my .h file.

As soon as I pressed the "(" key after typing the attribute name, the
Visual Studio UI locked up.  I had noticed before that it sometimes
remains unresponsive for seconds while it's looking up the
intellisense for an attribute, but this time it didn't come back at
all.

I don't know exactly how long it's been stuck now, but to give you an
idea: I waited for about a minute, then opened my newsreader, looked
up this thread, typed in this message, and it's still stuck when I
reach this point.



Sun, 25 Sep 2005 16:31:52 GMT  
 
 [ 6 post ] 

 Relevant Pages 

1. moving arrays from un-managed to managed code.

2. Managed array of managed arrays of char

3. Senior moment - fixed-size array passing

4. Array size >64k; easy fix

5. managed code vs. non-managed code

6. code size of managed dll very large?

7. Passing arrays from managed to unmanaged code

8. templates && managed code, managed args in virtual funcs

9. BUG in C++: array size passed to a C# code

10. qsorting & managing struct arrays, pointer arrays

11. Pointers to interfaces as Event args

12. ByRef Event Args Not Getting Through

 

 
Powered by phpBB® Forum Software