10

I want to convert System::String ^ to LPCWSTR.

for

FindFirstFile(LPCWSTR,WIN32_FIND_DATA); 

Please help.

Michael Fredrickson
  • 36,839
  • 5
  • 92
  • 109
Rick2047
  • 1,565
  • 7
  • 24
  • 35

4 Answers4

26

The easiest way to do this in C++/CLI is to use pin_ptr:

#include <vcclr.h>

void CallFindFirstFile(System::String^ s)
{
    WIN32_FIND_DATA data;
    pin_ptr<const wchar_t> wname = PtrToStringChars(s);
    FindFirstFile(wname, &data);
}
Bojan Resnik
  • 7,320
  • 28
  • 29
  • 1
    It should be noted that the `wname` points to the actual character data in `s`, not a copy thereof, which can make it more efficient than other marshaling solutions. (`const` hints at that) – Evgeniy Berezovsky Jan 31 '19 at 01:28
11

To convert a System::String ot LPCWSTR in C++/CLI you can you use the Marshal::StringToHGlobalAnsi function to convert managed strings to unmanaged strings.

System::String ^str = "Hello World";

IntPtr ptr = System::Runtime::InteropServices::Marshal::StringToHGlobalAnsi(str);

HANDLE hFind = FindFirstFile((LPCSTR)ptr.ToPointer(), data);

System::Runtime::InteropServices::Marshal::FreeHGlobal(ptr);
heavyd
  • 17,303
  • 5
  • 56
  • 74
2

You need to use P/Invoke. Check this link: http://www.pinvoke.net/default.aspx/kernel32/FindFirstFile.html

Simply add the DllImport native function signature:

 [DllImport("kernel32.dll", CharSet=CharSet.Auto)]
 static extern IntPtr FindFirstFile
     (string lpFileName, out WIN32_FIND_DATA lpFindFileData);

and CLR will do managed to native type marshaling automatically.

[Edit] I just realized you're using C++/CLI. In that case, you can also use implicit P/Invoke, which is a feature which only C++ supports (opposed to C# and VB.NET). This articles shows several examples:

How to: Convert Between Various String Types in C++/CLI

vgru
  • 49,838
  • 16
  • 120
  • 201
0

I have found that

String^ str = "C:\\my.dll";

::LoadLibraryEx(LPCWSTR)Marshal::StringToHGlobalAnsi(str).ToPointer(), 0, flags); 

does not work, returning code 87. Instead,

#include <atlstr.h>

CString s("C:\\my.dll");
::LoadLibraryEx((LPCWSTR)s, 0, flags);

has been working like a charm and seems to be the least verbose method.

Erikest
  • 4,997
  • 2
  • 25
  • 37