471,092 Members | 1,111 Online
Bytes | Software Development & Data Engineering Community
Post +

Home Posts Topics Members FAQ

Join Bytes to post your question to a community of 471,092 software developers and data experts.

Conversion of unmanaged structure containing array to the managed one!

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

Mar 26 '07 #1
16 8609
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?
Hi,

There is no need to convert the structure. You can use unmanaged structures
and classes like that in managed C++ (and C++/CLI for that matter) and it'll
just work.

--
Kind regards,
Bruno.
br**********************@hotmail.com
Remove only "_nos_pam"

Mar 28 '07 #2

<pk******@gmail.comwrote in message
news:11**********************@n76g2000hsh.googlegr oups.com...
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?
inline_array presented here:
http://blogs.msdn.com/branbray/archi...20/441099.aspx
>
Thx a lot,
Peter

Mar 28 '07 #3
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/archi...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.

Mar 29 '07 #4
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.

Mar 29 '07 #5
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, 50a;
inline_array<int, 100b;
};

str1 src;
str2^ dst;

How would you typecast src onto dst?

Thx a lot,
Peter.

Mar 30 '07 #6
pk******@gmail.com wrote:
>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, 50a;
inline_array<int, 100b;
};

str1 src;
str2^ dst;

How would you typecast src onto dst?
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
Mar 31 '07 #7

"Carl Daniel [VC++ MVP]" <cp*****************************@mvps.org.nospam >
wrote in message news:u2*************@TK2MSFTNGP05.phx.gbl...
pk******@gmail.com wrote:
>>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, 50a;
inline_array<int, 100b;
};

str1 src;
str2^ dst;

How would you typecast src onto dst?

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.
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!
Mar 31 '07 #8
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.

Mar 31 '07 #9
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?

Mar 31 '07 #10

<pk******@gmail.comwrote in message
news:11*********************@n76g2000hsh.googlegro ups.com...
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?
I think for your situation, it will work. But you must only use the
primitive data types.
>
Cheers,
Peter.

Apr 2 '07 #11
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.

Apr 3 '07 #12

<pk******@gmail.comwrote in message
news:11*********************@l77g2000hsb.googlegro ups.com...
>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 .....
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.

Apr 3 '07 #13
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.

Apr 4 '07 #14

<pk******@gmail.comwrote in message
news:11**********************@q75g2000hsh.googlegr oups.com...
>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.

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.
Apr 5 '07 #15
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
Dec 11 '07 #16
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."
Dec 11 '07 #17

This discussion thread is closed

Replies have been disabled for this discussion.

Similar topics

2 posts views Thread by Brian Keating | last post: by
11 posts views Thread by Peter Oliphant | last post: by
3 posts views Thread by =?Utf-8?B?U2hhcm9u?= | last post: by
17 posts views Thread by =?Utf-8?B?U2hhcm9u?= | last post: by
20 posts views Thread by =?Utf-8?B?VGhlTWFkSGF0dGVy?= | last post: by

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.