String^ to LPCTSTR in VC++2010 (Windows form application)

烈酒焚心 提交于 2019-12-24 12:30:31

问题


How to convert System::string^ in to LPCTSTR ? As my requirement is to clone a file using function CopyFile, it works fine if i give Fix name (OldFile.jpg and LatestFile.jpg) to its parameters (below Code: Works Fine)

LPCTSTR in_f,out_f;

in_f    =   _T("d:\\Old.jpg");
out_f   =   _T("d:\\Latest.jpg");

CopyFile(in_f,out_f,false);

above code clone the Old.jpeg in to a Latest.jpg but when i trying to give name (Latest.jpg) which is coming out from some String it won't create file (below Code: NOT Working)

  String^   Name    =   "Latest";

//------Capture Current Date & Time
    DateTime datetime = DateTime::Now;

//-------Convert Date Timt in to String
    Name    =   Name + String::Format("{0}",datetime); 
    Name    =   Name->Replace('/','-');
    Name    =   Name->Replace(':','-');
    Name    =   Name    +   ".jpg";    

    LPCTSTR in_f,out_f;

    in_f    =   _T("d:\\Old.jpg");
    out_f   =   (LPCTSTR)Name; //Trying to Assign Current Latest file Name With date Time here

    CopyFile(in_f,out_f,false);

The Problem is CopyFile Took LPCTSTR type as an argument , where as i am giving a type System::string^, So suggest me how to convert this System::string^ in to LPCTSTR so that i can add the current date time with in the name of my file. I am Using VC++2010 and Windows form Application


回答1:


Standard warning: While it's certainly possible to write the main body of your application in C++/CLI, or even write the GUI in C++/CLI using WinForms, it is not recommended. C++/CLI is intended for interop scenarios: where C# or other .Net code needs to interface with unmanaged C++, C++/CLI can provide the translation between the two. For primary development, it is recommended to use C# with either WinForms or WPF if you want managed code, or C++ with MFC if you want unmanaged.


I'm not sure I agree with Hans's comment that TCHAR is obsolete, but doing an explicit conversion to a wide string and calling CopyFileW is a good option.

Also, one could go the other direction, and convert from unmanaged to managed strings, and use the .Net method to copy files, File::Copy(String^, String^, Boolean).

To convert to a LPCTSTR, I would use marshal_as. Because it's implemented with templates, the compiler will resolve your LPCTSTR to call either the LPCSTR or LPCWSTR version, as appropriate.

Microsoft doesn't have dedicated documentation pages for each templated version of marshal_as, but the Overview of Marshaling in C++ page is a good place to start.

My test program:

#include <msclr\marshal.h>

int main(array<System::String^>^ args)
{
    String^ managedStr = "I came from managed land!\r\n";

    // This controls the lifetime of the LPCTSTR that marshal_as returns. 
    // When this goes out of scope, the LPCTSTR will no longer be valid, 
    // so be aware of its lifetime.
    msclr::interop::marshal_context context;

    LPCTSTR unmanagedStr = context.marshal_as<LPCTSTR>(managedStr);

    OutputDebugString(unmanagedStr);

    return 0;
}

Result:

I came from managed land!



回答2:


You need to append a \0 character at the end of the Name string, since CopyFile() expects zero-terminated strings.

EDIT: As LucasTrzesniewski has pointed out, pinning a .NET string automatically yields a zero-terminated character array. This is documented in the C# specification. See the comments below for more information.

Moreover, you have to "pin" the string in memory, so the garbage collector won't move it around. Then you can create a pointer to the first character of the string. C++/CLI provides some utility types and functions to do this. Here's an example:

pin_ptr<const WCHAR> psName = PtrToStringChars (Name)

PtrToStringChars() is an inline function declared in vcclr.h. psName should be assignable to a LPCTSTR parameter - if not, use a cast. Note that PtrToStringChars() doesn't work if the input string is a nullptr. You need to test explicitly for this case. (However, in your case, Name is certainly not a nullptr).

The String remains pinned until the variable psName gets out of scope. This happens after leaving the { ... } block in which it's declared, e.g. after leaving the current function. No explicit unpinning is needed.




回答3:


You need to marshaling it to "const char *" and make a static_cast to LPCTSTR.

Take a look at this https://msdn.microsoft.com/en-us/library/bb384865.aspx



来源:https://stackoverflow.com/questions/46115050/string-to-lpctstr-in-vc2010-windows-form-application

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!