Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Conversion of unmanaged structure containing array to the managed one!

26 views
Skip to first unread message

pkon...@gmail.com

unread,
Mar 26, 2007, 4:28:54 AM3/26/07
to
Hello everybody,

Been just thinking how actually one could convert the following
unmanaged code to the managed C++:

struct JustAnExample
{
char value1[100];
int value2[120];
// etc ....
}

There're numerous examples how to cope with unamnaged C++ to C#
conversions, but I don't find marshaling that attractive and necessary
since managed C++ types are available for C#. So, any idea?

Thx a lot,
Peter

Ben Voigt

unread,
Mar 28, 2007, 4:01:38 PM3/28/07
to

<pkon...@gmail.com> wrote in message
news:1174897734.6...@n76g2000hsh.googlegroups.com...

inline_array presented here:
http://blogs.msdn.com/branbray/archive/2005/07/20/441099.aspx

>
> Thx a lot,
> Peter
>


pkon...@gmail.com

unread,
Mar 29, 2007, 4:35:29 AM3/29/07
to

> > There're numerous examples how to cope with unamnaged C++ to C#
> > conversions, but I don't find marshaling that attractive and necessary
> > since managed C++ types are available for C#. So, any idea?
>
> inline_array presented here:http://blogs.msdn.com/branbray/archive/2005/07/20/441099.aspx

Hi.

I'm getting error "C2988: unrecognizable template declaration/
definition" while compiling that static_array template. What's the
matter? It seems that this is due to the partial specializator. How
did u get it compiled then on MSVC 2005?

Cheers,
Peter.

pkon...@gmail.com

unread,
Mar 29, 2007, 4:45:44 AM3/29/07
to
> I'm getting error "C2988: unrecognizable template declaration/
> definition" while compiling that static_array template. What's the
> matter? It seems that this is due to the partial specializator. How
> did u get it compiled then on MSVC 2005?

OK. False alarm! ;p

Cheers.

pkon...@gmail.com

unread,
Mar 30, 2007, 5:16:42 AM3/30/07
to
> OK. False alarm! ;p
> Cheers.

Hmm, there's one more question.

I aim at casting an unmanaged structure onto managed one. Let's give
consideration to the following:
struct str1
{
char a[50];
int b[100];
};

typedef ref struct str2
{
inline_array<char, 50> a;
inline_array<int, 100> b;
};

str1 src;
str2^ dst;

How would you typecast src onto dst?

Thx a lot,
Peter.

Carl Daniel [VC++ MVP]

unread,
Mar 30, 2007, 9:24:11 PM3/30/07
to

You cannot cast between these types. you can write a function (e.g.
constructor or conversion function) to copy an instance of str1 to str2, but
there's no way to fool the CLR into accepting a native struct as if it were
a managed struct.

-cd


Ben Voigt

unread,
Mar 31, 2007, 12:19:39 PM3/31/07
to

"Carl Daniel [VC++ MVP]" <cpdaniel_remove...@mvps.org.nospam>
wrote in message news:u2qUKNz...@TK2MSFTNGP05.phx.gbl...

Let's think about what would happen if you could cast a native struct to a
ref class and then pass it to a managed API. The native struct can be
stored on the native heap or the stack. It's safe as far as being moved
during garbage collection, because neither of those memory areas get
compacted.... but the managed code could stuff said ref class instance with
a handle to another ref class. If the original area is on the stack, no
problem. But if it was on the native heap, when you return to C++ code,
there is a reference to that second ref class from the native heap. The
garbage collection might run, and then everything goes south. The GC
doesn't search the native heap for references, so if that's the only
reference, it will consider the second object unreachable and remove it. If
there are other references, it will be moved during compaction. Either way,
the native heap is left holding a dangling reference -- not good!


pkon...@gmail.com

unread,
Mar 31, 2007, 6:00:17 PM3/31/07
to
Hmm.

All what I want to achieve is sth that the following example
illustrates:

// C++ unmanaged


struct str1
{
char a[50];
int b[100];
};

class cl1
{
...
str1 arr1[100];
...
}

// C++ managed wrapper here

// C#
[StructLayout(LayoutKind.Explicit, Size=2040)]
public struct str2
{
[FieldOffset(0), MarshalAs(UnmanagedType.U1, SizeConst=50)]
public sbyte a;
[FieldOffset(50), MarshalAs(UnmanagedType.I4, SizeConst=100)]
public sbyte b;
}

str2* arr2;

Now, using c++ managed wrapper I cast arr1 onto arr2 pointer in unsafe
block (C# site) and enjoy access as long as wrapper isn't destroyed
along with unmanaged class instance. That works fine (hope there are
no garbage collettor issues involved...), though I just wanted to cast
unmanaged struct onto managed c++ struct first (the best declared on
C# site), so not to utilize that aforementioned struct declared in C#,
but go intermediate from unmanaged C++ structure casting onto managed C
++ structure (its instance declared on C# site). Is it viable?

Cheers,
Peter.

pkon...@gmail.com

unread,
Mar 31, 2007, 6:10:38 PM3/31/07
to
Ahhh.

What's important to stress, I just read unmanaged above data from the
level of C#, though do not write to it, do not attach/cast onto any
structures created in the managed code. That's the principle. To have
the access to unmanaged structures so to read them without previous
data copyig. I assume that Marshal::PtrToStructure will rather copy
data. Is that right?

Ben Voigt

unread,
Apr 2, 2007, 3:16:46 PM4/2/07
to

<pkon...@gmail.com> wrote in message
news:1175378417....@n76g2000hsh.googlegroups.com...

I think for your situation, it will work. But you must only use the
primitive data types.

>
> Cheers,
> Peter.
>


pkon...@gmail.com

unread,
Apr 3, 2007, 4:00:22 AM4/3/07
to
> I think for your situation, it will work. But you must only use the
> primitive data types.

I think so too, though there's still the question, how to prepare a
managed C++ structure equivalent to the above-given in C# (along with
casting operations - that's what bugges me). I'm stuck with respect to
that .....

Cheers,
P.

Ben Voigt

unread,
Apr 3, 2007, 9:27:30 AM4/3/07
to

<pkon...@gmail.com> wrote in message
news:1175587222....@l77g2000hsb.googlegroups.com...

Ok, I'm still not understanding your overall design well enough. What
function will create the structure, and where will it be passed?

>
> Cheers,
> P.
>


pkon...@gmail.com

unread,
Apr 4, 2007, 4:14:54 AM4/4/07
to
> Ok, I'm still not understanding your overall design well enough. What
> function will create the structure, and where will it be passed?

The structure is returned by a dll library method. Then, it's wrapped
in unmanaged C++ where a few of extra actions are performed (speed
critical and so forth). Then, the whole unmanaged C++ class is wrapped
as a managed C++ one providing decent interface for C#. The structure
that I talk about consists of a few of fields of char[255] type
indicating some device properties and, actually, I can pass it as it
is to C# so to display it. The way I do it is casting the pointer to
the structure onto void* in managed C++, then casting that pointer
onto C# structure on C# site by calling managed C++ method returning
void* (unsafe code). So, what I want to achieve is casting that
unmanaged structure onto managed C++ one first. All what I need is an
example of casting the following:


struct str1
{
char a[50];
int b[100];
};

onto C++ managed structure str2 (how to do that without copying or
PtrToStructure method utilizing?)

then str2 onto C# structure:

[StructLayout(LayoutKind.Explicit, Size=2040)]
public struct str2
{
[FieldOffset(0), MarshalAs(UnmanagedType.U1, SizeConst=50)]
public sbyte a;
[FieldOffset(50), MarshalAs(UnmanagedType.I4, SizeConst=100)]
public sbyte b;

}


Hope this clarifies good enough the issue,
Peter.

Ben Voigt

unread,
Apr 5, 2007, 9:49:44 AM4/5/07
to

<pkon...@gmail.com> wrote in message
news:1175674494.1...@q75g2000hsh.googlegroups.com...


Yes, that is the ideal level of description. Now we can solve your problem
instead of helping you with the hack you chose.

Store the data as a native structure allocated on the native heap. Store a
pointer in your managed wrapper (ref class). Don't forget to call delete or
free from your finalizer and preferably also include a
destructor/IDisposable implementation. There are some smart pointer classes
around that will make this really easy.

Now, you needn't any equivalent managed structure at all. Define accessor
functions to access individual fields of the structure, the JIT interpreter
should end up inlining these and in effect C# gains the ability to read and
write native C++ buffers. If your char[256] fields represent binary data,
you're done. If they are human-readable strings, then you'll want to
convert to System::String^. This will always require a copy, because you
have to convert to unicode. So the trick is to do it as few times as
possible. Declare System::String^ members in your wrapper and initialize to
nullptr. Use these to cache the conversion result, and only if the managed
String isn't set yet, use Marshal::PtrToStringAscii to do the conversion.

Hope this helps.


shikhagupta

unread,
Dec 11, 2007, 12:55:53 AM12/11/07
to
Hi,

I am facing a similar problem.The structures that I have contains an odd 100 elements.
What it means by writing accesor functions.Can you please provide some examples?

Regards
Shikha

EggHeadCafe - .NET Developer Portal of Choice
http://www.eggheadcafe.com

Kerem Gümrükcü

unread,
Dec 11, 2007, 1:07:32 AM12/11/07
to
Hi Shikha,

can you give us a example of a struct that
you want to convert to managed code, so
that we can give you a example. But the
Code should be like the one you will use
in your managed code, best would be
original structure,...


Regards

Kerem

--
-----------------------
Beste Grüsse / Best regards / Votre bien devoue
Kerem Gümrükcü
Microsoft Live Space: http://kerem-g.spaces.live.com/
Latest Open-Source Projects: http://entwicklung.junetz.de
-----------------------
"This reply is provided as is, without warranty express or implied."


0 new messages