0

Development environment: Win32 Desktop Application C++/CLI

Let's have an array like this:

array<String^>^ strArr = gcnew array<String^>(100);

An array like this too:

void* ptrArr[100];

I have to copy all the first array's elements to second array. How to do this?

1 Answer 1

1

I'm assuming that void* ptrArr[100] is actually const char* ptrArr[100]. void* could be literally anything, so there's no way to answer the question without making an assumption about the type.

So, you need two things here: You need to do the conversion between types (including from Unicode code points to ANSI characters), and you need to have something own that memory.

There's a few choices as to what should hold the unmanaged memory for the const char*. The most do-it-yourself route is Marshal.StringToHGlobalAnsi, but that's a pain so we're going to skip that. (This would require manually keeping track of a bunch of IntPtr, and manually calling FreeHGlobal when done.)

The other choices are different invocations of marshal_as.

You could convert all the String^ instances into std::string instances, and pull the const char* out of them. I recommend marshal_as<std::string> for this. In this case, the memory is owned by the std:string instances, so ptrArr will be valid only for as long as stdStrArr is.

#include <msclr\marshal_cppstd.h>

array<String^>^ strArr = gcnew array<String^>(100);
std::string stdStrArr[100];
const char* ptrArr[100];

for (size_t i = 0; i < 100; i++)
{
    stdStrArr[i] = marshal_as<std::string>(strArr[i]);
    ptrArr[i] = stdStrArr[i].c_str();
}
// Memory for ptrArr deallocated when stdStrArr goes out of scope. 

The other choice is to use marshal_as to convert directly to const char*. To do this, you allocate a helper object. In this case, the memory is owned by the marshal_context instance, so ptrArr will be valid only for as long as context is.

#include <msclr\marshal.h>

array<String^>^ strArr = gcnew array<String^>(100);
marshal_context^ context = gcnew marshal_context();
char* ptrArr[100];

for (size_t i = 0; i < 100; i++)
{
    ptrArr[i] = context->marshal_as<const char*>(strArr[i]);
}
// Memory for ptrArr deallocated when you call `delete context`, or when it's garbage collected. 

Further reading:

Notes:

  • I didn't check my syntax with a compiler. There may be small errors.
  • It seems like there should be a question to mark this one a duplicate. However, I wasn't able to find a "convert String^ to char*" question that was highly-rated, used marshal_as in the answer, and showed a good example of how to use it.
Sign up to request clarification or add additional context in comments.

1 Comment

Of course, Unicode to any "ANSI" character set could be very lossy.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.