Click here to Skip to main content
15,885,852 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
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.
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

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