Click here to Skip to main content
15,921,793 members
Please Sign up or sign in to vote.
2.60/5 (2 votes)
See more:
I have a dll file bilt by C++, in that one contains a function with parameter is LPCWSTR, i want to call this function in C#, but I dont know which data type in C# equivalent with that data type, please help me solve this problem, thanks.
Posted
Comments
[no name] 17-Sep-12 9:33am    
try a string
Andrewpeter 17-Sep-12 9:46am    
I have used string, but it didnt display exactly, this is dll code:
HRESULT _stdcall CreateLink(LPCWSTR lpszPathObj, LPCSTR lpszPathLink, LPCWSTR lpszDesc)
{
HRESULT hres;
IShellLink* psl;

// Get a pointer to the IShellLink interface. It is assumed that CoInitialize
// has already been called.
hres = CoCreateInstance(CLSID_ShellLink, NULL, CLSCTX_INPROC_SERVER, IID_IShellLink, (LPVOID*)&psl);
if (SUCCEEDED(hres))
{
IPersistFile* ppf;

// Set the path to the shortcut target and add the description.
psl->SetPath(lpszPathObj);
psl->SetDescription(lpszDesc);

// Query IShellLink for the IPersistFile interface, used for saving the
// shortcut in persistent storage.
hres = psl->QueryInterface(IID_IPersistFile, (LPVOID*)&ppf);

if (SUCCEEDED(hres))
{
WCHAR wsz[MAX_PATH];

// Ensure that the string is Unicode.
MultiByteToWideChar(CP_ACP, 0, lpszPathLink, -1, wsz, MAX_PATH);

// Add code here to check return value from MultiByteWideChar
// for success.

// Save the link by calling IPersistFile::Save.
hres = ppf->Save(wsz, TRUE);
ppf->Release();
}
psl->Release();
}
return hres;
}

This function is used to create a shortcut file, I compiled it to dll successfully, I called it in C# as follows:

[DllImport("abc.dll")]
private static extern long CreateLink(string lpszPathObj, string lpszPathLink, string lpszDesc);

public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
long h=CreateLink("C:\\abc.exe",Environment.GetFolderPath(Environment.SpecialFolder.Desktop)+"\\abc.lnk","asdada");
}

When I press button, a shortcut file display on Desktop, but it doent path to abc.exe; when I show the Properties of this shortcut file I receive at Target field: C:\Users\Peter\Desktop\㩃呜䅒啃䑕乁攮數; it contains Chinese string, why? Hope you help me. Thanks.
CPallini 17-Sep-12 10:31am    
I suppose your troubles come from LPCSTR (not from LPCWSTR), however, have a look at http://msdn.microsoft.com/en-us/library/s9ts558h(VS.100).aspx
pasztorpisti 17-Sep-12 9:36am    
LPCWSTR is const wchar_t*, its most likely to be an utf16 encoded string that is the native format of WinNT.
Andrewpeter 17-Sep-12 9:48am    
What I do have to do now? Thanks.

With P/Invoke, you can specify the mapping to use for string type. This is explained here for C++ code but the same apply to C#. You simply put attribute on the declaration to tell the compiler how to convert types.

You would add that to the string parameter : [MarshalAs(UnmanagedType::LPArray)] when importing functions.

http://msdn.microsoft.com/en-us/library/s97shtze(v=vs.110).aspx[^]

You should be able to find more information in documentation or on the web.
 
Share this answer
 
v2
XML
Try this:

void CManagedClass::SetStr( String ^ theString ) {
     CUnmanagedClass m_Impl;
     pin_ptr<const WCHAR> str = PtrToStringChars(theString);
     m_Impl.SetString( str );
  }
 
Share this answer
 
Comments
CHill60 23-Apr-13 9:49am    
OP wants to call his C++ DLL from C# ... this isn't C# ;-p
Try using Marshal.StringToHGlobalAnsi[^]
to convert managed string to unmanaged string (returns IntPtr pointing to converted string).
Then change import declaration to use IntPtr:
C#
[DllImport("abc.dll")] private static extern long CreateLink(IntPtr lpszPathObj, string lpszPathLink, IntPtr lpszDesc);

I'm not sure if 2nd param should also be converted.

There is article here that might help:
Creating and Resolving shell links[^]

There is also an iterop here, no need for C++ dll:
http://www.msjogren.net/dotnet/eng/samples/dotnet_shelllink.asp[^]
 
Share this answer
 
v4
Comments
Andrewpeter 17-Sep-12 10:38am    
How will i call that function (in button1_Click() above). Thanks.
Andrewpeter 17-Sep-12 10:45am    
Oh, I used it, but not work!

My code:

[DllImport("abc.dll")]
private static extern long CreateLink(IntPtr lpszPathObj, string lpszPathLink, IntPtr lpszDesc);

public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
String str1 = "C:\\abc.exe";
String str2 = "abccvc";
IntPtr pstr1 = (IntPtr)Marshal.StringToHGlobalAnsi(str1);
IntPtr pstr2 = (IntPtr)Marshal.StringToHGlobalAnsi(str2);
long h = CreateLink(pstr1, Environment.GetFolderPath(Environment.SpecialFolder.Desktop) + "\\abc.lnk", pstr2);
}

Please help me. Thanks.
sjelen 17-Sep-12 11:28am    
Take a look at url in updated solution.
It looks like Marshal.StringToCoTaskMemUni() should be used.
Andrewpeter 17-Sep-12 11:41am    
Thank you, I'll use it, my vote is 5 for your answer, thanks.
Philippe Mori 23-Apr-13 22:53pm    
You should specify mapping using attributes. See my solution.

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)



CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900