PC Review


Reply
Thread Tools Rate Thread

Converting native arrays to managed arrays

 
 
Bob Altman
Guest
Posts: n/a
 
      27th Feb 2008
Hi all,

I'm writing C++/CLI code (compiled with /clr) that accepts a native char array
(and its length) and calls a managed routine that expects an array of
System::Byte. I was just wondering if there is any magic that I'm missing that
easily marshals the native array into a managed array, or do I need to write my
own code to allocate the managed array<> and loop through it copying the native
data into the managed array?

TIA - Bob


 
Reply With Quote
 
 
 
 
Mark Salsbery [MVP]
Guest
Posts: n/a
 
      27th Feb 2008
"Bob Altman" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> Hi all,
>
> I'm writing C++/CLI code (compiled with /clr) that accepts a native char
> array (and its length) and calls a managed routine that expects an array
> of System::Byte. I was just wondering if there is any magic that I'm
> missing that easily marshals the native array into a managed array, or do
> I need to write my own code to allocate the managed array<> and loop
> through it copying the native data into the managed array?


You can use System::Runtime::InteropServices::Marshal::Copy(), which does
the "loop through it copying " part for you

Mark

--
Mark Salsbery
Microsoft MVP - Visual C++

>
> TIA - Bob
>

 
Reply With Quote
 
Bob Altman
Guest
Posts: n/a
 
      27th Feb 2008
> You can use System::Runtime::InteropServices::Marshal::Copy(), which does the
> "loop through it copying " part for you
>
> Mark


Thanks Mark!


 
Reply With Quote
 
Bob Altman
Guest
Posts: n/a
 
      27th Feb 2008
"Mark Salsbery [MVP]" <MarkSalsbery[MVP]@newsgroup.nospam> wrote in message
news:BD264A84-

> You can use System::Runtime::InteropServices::Marshal::Copy(), which does the
> "loop through it copying " part for you


I've tried several variations on the following code, but it complains that it
can't find an overload for Marshal::Copy that it likes. I suspect that it
doesn't like the boxed handle to an IntPtr that I think I'm trying to feed it
(by way of the gcnew IntPtr() code). How do I cast a char* to an IntPtr?

const char* value = <some array of bytes>
int size = 15;
array<unsigned char>^ myArray = gcnew array<unsigned char>(size);
Marshal::Copy(gcnew IntPtr((void*)value), myArray, 0, size);


 
Reply With Quote
 
Mark Salsbery [MVP]
Guest
Posts: n/a
 
      27th Feb 2008
"Bob Altman" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> "Mark Salsbery [MVP]" <MarkSalsbery[MVP]@newsgroup.nospam> wrote in
> message news:BD264A84-
>
>> You can use System::Runtime::InteropServices::Marshal::Copy(), which does
>> the "loop through it copying " part for you

>
> I've tried several variations on the following code, but it complains that
> it can't find an overload for Marshal::Copy that it likes. I suspect that
> it doesn't like the boxed handle to an IntPtr that I think I'm trying to
> feed it (by way of the gcnew IntPtr() code). How do I cast a char* to an
> IntPtr?
>
> const char* value = <some array of bytes>
> int size = 15;
> array<unsigned char>^ myArray = gcnew array<unsigned char>(size);
> Marshal::Copy(gcnew IntPtr((void*)value), myArray, 0, size);
>
>


Maybe try something like this:

const char *value = new char[100];
int size = 15;
array<unsigned char>^ myArray = gcnew array<unsigned char>(size);
Marshal::Copy(IntPtr(const_cast<void*>(static_cast<const void*>(value))),
myArray, 0, size);
delete[] value;

Mark

--
Mark Salsbery
Microsoft MVP - Visual C++

 
Reply With Quote
 
Mark Salsbery [MVP]
Guest
Posts: n/a
 
      27th Feb 2008
Also note that in my code sample, it ends up using the

Marshal::.Copy Method (IntPtr, array<Byte>[]()[], Int32, Int32)

form of Marshall::Copy() since the array is a Byte (unsigned char) array.

Cheers,
Mark

--
Mark Salsbery
Microsoft MVP - Visual C++


"Bob Altman" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
> "Mark Salsbery [MVP]" <MarkSalsbery[MVP]@newsgroup.nospam> wrote in
> message news:BD264A84-
>
>> You can use System::Runtime::InteropServices::Marshal::Copy(), which does
>> the "loop through it copying " part for you

>
> I've tried several variations on the following code, but it complains that
> it can't find an overload for Marshal::Copy that it likes. I suspect that
> it doesn't like the boxed handle to an IntPtr that I think I'm trying to
> feed it (by way of the gcnew IntPtr() code). How do I cast a char* to an
> IntPtr?
>
> const char* value = <some array of bytes>
> int size = 15;
> array<unsigned char>^ myArray = gcnew array<unsigned char>(size);
> Marshal::Copy(gcnew IntPtr((void*)value), myArray, 0, size);
>
>

 
Reply With Quote
 
Bob Altman
Guest
Posts: n/a
 
      27th Feb 2008
> Maybe try something like this:
>
> const char *value = new char[100];
> int size = 15;
> array<unsigned char>^ myArray = gcnew array<unsigned char>(size);
> Marshal::Copy(IntPtr(const_cast<void*>(static_cast<const void*>(value))),
> myArray, 0, size);
> delete[] value;


Thanks, that works. I didn't realize that I could create an IntPtr (not a
*reference* to an IntPtr) like that. BTW, you don't need the double cast
because you can pass a char* to the IntPtr constructor (which it widens to a
void*), so the resultant expression looks like this:

Marshal::Copy(IntPtr(const_cast<char*>(value)), myArray, 0, size);


 
Reply With Quote
 
Mark Salsbery [MVP]
Guest
Posts: n/a
 
      27th Feb 2008
"Bob Altman" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
>> Maybe try something like this:
>>
>> const char *value = new char[100];
>> int size = 15;
>> array<unsigned char>^ myArray = gcnew array<unsigned char>(size);
>> Marshal::Copy(IntPtr(const_cast<void*>(static_cast<const void*>(value))),
>> myArray, 0, size);
>> delete[] value;

>
> Thanks, that works. I didn't realize that I could create an IntPtr (not a
> *reference* to an IntPtr) like that. BTW, you don't need the double cast
> because you can pass a char* to the IntPtr constructor (which it widens to
> a void*), so the resultant expression looks like this:
>
> Marshal::Copy(IntPtr(const_cast<char*>(value)), myArray, 0, size);


Ahh excellent, thanks I could have sworn I tried that and got an
error....I must have mis-typed something.

Thanks again,
Mark

--
Mark Salsbery
Microsoft MVP - Visual C++


>
>

 
Reply With Quote
 
Mark Salsbery [MVP]
Guest
Posts: n/a
 
      27th Feb 2008
"Bob Altman" <(E-Mail Removed)> wrote in message
news:(E-Mail Removed)...
>> Maybe try something like this:
>>
>> const char *value = new char[100];
>> int size = 15;
>> array<unsigned char>^ myArray = gcnew array<unsigned char>(size);
>> Marshal::Copy(IntPtr(const_cast<void*>(static_cast<const void*>(value))),
>> myArray, 0, size);
>> delete[] value;

>
> Thanks, that works. I didn't realize that I could create an IntPtr (not a
> *reference* to an IntPtr) like that.



Oops almost forgot - IntPtr is a value class, so you can use it that way,
and Marshal.Copy() expects it that way, not an IntPtr^.

Cheers,
Mark

--
Mark Salsbery
Microsoft MVP - Visual C++



>BTW, you don't need the double cast because you can pass a char* to the
>IntPtr constructor (which it widens to a void*), so the resultant
>expression looks like this:
>
> Marshal::Copy(IntPtr(const_cast<char*>(value)), myArray, 0, size);
>
>

 
Reply With Quote
 
 
 
Reply

Thread Tools
Rate This Thread
Rate This Thread:

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are Off


Similar Threads
Thread Thread Starter Forum Replies Last Post
using managed arrays ??? Chris Microsoft VC .NET 5 24th Aug 2004 03:55 PM
Re: using managed arrays ??? Chris Microsoft VC .NET 0 24th Aug 2004 08:30 AM
Managed C++ - Arrays, Handles =?Utf-8?B?S2V2aW4gQnVydG9u?= Microsoft Dot NET Framework 1 16th Jul 2004 12:07 PM
Managed C++ and Jagged Arrays =?Utf-8?B?UGF1bFc=?= Microsoft VC .NET 3 6th May 2004 08:51 AM
Passing managed arrays jlea Microsoft VC .NET 6 16th Jul 2003 12:37 PM


Features
 

Advertising
 

Newsgroups
 


All times are GMT +1. The time now is 07:54 AM.