Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Need to convert String^ to char *

I am using the .NET DateTime to get the current date and time. I am converting it to a string to use as part of a file name. The problem is the OpenCV command to save an image requires a char * not a string type, and DateTime will only output a String^ type. How do I make this work? Heres the code not completed

String^ nowString = DateTime::Now.ToString("yyyy-MM-dd-HH:mm");
        IplImage* toSave;
        CvCapture* capture = cvCreateCameraCapture(0);
        toSave = cvQueryFrame( capture );
        cvSaveImage(nowString, toSave);
        cvReleaseImage(&toSave);
        cvReleaseCapture(&capture);
like image 881
kman99 Avatar asked Feb 01 '10 16:02

kman99


People also ask

Is char * Same as string?

Yes, char* is the pointer to an array of character, which is a string.

Can you convert string to char?

We can convert String to char in java using charAt() method of String class. The charAt() method returns a single character only. To get all characters, you can use loop.

Can you set a string to a char * C++?

You can't really "assign a string" to a char * , because although a char* parameter is sometimes referred to as a "string parameter", it isn't actually a string, it's a pointer (to a string). If you're getting heap corruption, then the problem isn't the assignment, the problem is your management of allocated memory.

What is a char * in C++?

char* is typically used to iterate through a character array, i.e., a C string. It is rarely used as a pointer to a single char, unlike how other pointers are typically used. C++ has newer constructs for strings that typically should be used.


2 Answers

Your best bet is to use StringToHGlobalAnsi. Here is complete code showing how its done and remembering to free the memory allocated.

using namespace System::Runtime::InteropServices;

void MethodName()
{
    String^ nowString = DateTime::Now.ToString("yyyy-MM-dd-HH:mm");
    IntPtr ptrToNativeString = Marshal::StringToHGlobalAnsi(nowString);
    try
    {
        CvCapture* capture = cvCreateCameraCapture(0);
        IplImage* toSave = cvQueryFrame(capture);
        cvSaveImage(static_cast<char*>(ptrToNativeString.ToPointer()), toSave);
        cvReleaseImage(&toSave);
        cvReleaseCapture(&capture);
    }
    catch (...)
    {
        Marshal::FreeHGlobal(ptrToNativeString);
        throw;
    }
    Marshal::FreeHGlobal(ptrToNativeString);
}

You might want to rethink using a ':' character in the filename, as I don't believe windows likes this very much.

like image 193
mcdave Avatar answered Oct 04 '22 08:10

mcdave


Actually, I found the easiest way to get a char * from a String^ is to use good ol' sprintf(). So in your case, you can simple do this:

char cNow[17] = { 0 };
String^ nowString = DateTime::Now.ToString("yyyy-MM-dd-HH:mm");
if (nowString->Length < sizeof(cNow)) // make sure it fits & allow space for null terminator
  sprintf(cNow, "%s", nowString);

No need to call the Marshal functions!

Update

So it appears that VS 2015 adheres more closely to the C++11 standards, so using sprintf() with the .NET String won't work. The easiest way is to use the marshal_as() function like this:

Include these lines before your code:

#include <msclr/marshal_cppstd.h>
using namespace msclr::interop;

Then this should work:

char cNow[17] = { 0 };
String^ nowString = DateTime::Now.ToString("yyyy-MM-dd-HH:mm");
string sNow = marshal_as<string>(nowString);
if (sNow.length() < sizeof(cNow)) // make sure it fits & allow space for null terminator
  sprintf(cNow, "%s", sNow.c_str());

Otherwise, if you don't want to use the marshal_as() function, you can copy the string character by character like this:

char cNow[17] = { 0 };
String^ nowString = DateTime::Now.ToString("yyyy-MM-dd-HH:mm");
if (nowString->Length < sizeof(cNow)) // make sure it fits & allow space for null terminator
{
    for (int i = 0; i < nowString->Length; i++)
        cNow[i] = static_cast<char>(nowString[i]);
}
like image 26
Ionian316 Avatar answered Oct 04 '22 08:10

Ionian316