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 / Languages / Managed C++ / May 2005

Tip: Looking for answers? Try searching our database.

C++/CLI array in struct

Thread view: 
Enable EMail Alerts  Start New Thread
Thread rating: 
GrkEngineer - 06 May 2005 18:58 GMT
I recently had to use someone's struct from a native app to receive data over
Udp. The struct has a array member which looked like this:

struct sensorHdr{
     char sName[64];
};

When I tried to make this a managed struct by adding either the value struct
or ref struct I received a compile error stating that mixed types are not
supported. I understand this, but I don't know how to create a char array in
a C++/CLI struct using the array<Byte>(64) format.

Thanks
Nick
Tamas Demjen - 07 May 2005 00:37 GMT
> I recently had to use someone's struct from a native app to receive data over
> Udp. The struct has a array member which looked like this:
[quoted text clipped - 10 lines]
> Thanks
> Nick

Yes, array<Byte>(64) looks good to me, and this code compiles and seems
to work fine:

ref class sensorHdr
{
public:
   cli::array<char> ^ sName;
   sensorHdr(): sName( gcnew cli::array<char>(64) ) {}
};

You just have to pin the pointer before you pass it to a native API call:

cli::pin_ptr<char> s( & sName[0] );
CallCFunction(s);

Pinning means the .NET framework locks the location of the array in the
memory, preventing any possible relocation while your native code is
working on it.

Give it a try. Here's an alternative solution:

ref class sensorHdr
{
public:
   char* sName;
   sensorHdr() : sName(new char[64]) { }
   ~sensorHdr() { delete [] sName; }
};

This one compiles too, however, when this class is used from C#, for
example, you must call Dispose on it, to prevent unmanaged memory leak.
You may want to add a finalizer too. I'd go with the array<char>.

Tom
GrkEngineer - 07 May 2005 01:07 GMT
Tamas,

Thanks for the help. I just have a couple questions more. I noticed you used
ref class instead of ref struct. Will this still work as a struct or is there
no difference because you declared the members public? Can I pass a pinned
ref class over network or shared memory and have the native program receive
it as a struct? Also, will the sizeof(sensorHdr) give me the correct size. I
know using the second approach with the pointer will not. But will using the
cli::array?

Nick

> > I recently had to use someone's struct from a native app to receive data over
> > Udp. The struct has a array member which looked like this:
[quoted text clipped - 45 lines]
>
> Tom
Tamas Demjen - 09 May 2005 17:54 GMT
Nick,

I think ref struct is almost the same as ref class, the only difference
is whether members are public or private by default.

No, I don't think you should pass a ref class to unmanaged code.
Although it may seem your class is not inherited from anything and it
only declares one member, it actually is inherited from System::Object,
the parent of all .NET classes, and it most likely has implicit members
that you don't know of. Most importantly, you don't know the memory
layout, and you don't know what's inside the array container (I
guarantee you it's not a raw storage, it has further members, such as
the length of the array). You should only pin the handle to the array's
first item:

cli::pin_ptr<char> s( & sName[0] );

sizeof(sensorHrd) is most likely not 64. Don't rely on that. Instead,
use sName->Length to get the number of items in the array (which is the
size of the array in bytes in your case).

I think a .NET array is guaranteed to be contiguous in the memory, at
least this link claims it is:
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dv_vstechart/ht
ml/datastructures_guide.asp


Most containers aren't, but array is, as long as it stores value types
(such as char).

BTW, you have two more options: System::String, and memory stream. They
both allocate contiguous memory. I'd still use array<char>, which is a
wrapper around System::Array. Would use memory stream if I wanted to
append data dynamically to it.

Tom

> Tamas,
>
[quoted text clipped - 7 lines]
>
> Nick

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.