Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++ C#
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 17-Sep-12 3:33am
Comments
Wes Aday at 17-Sep-12 9:33am
   
try a string
Andrewpeter at 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 at 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 at 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 at 17-Sep-12 9:48am
   
What I do have to do now? Thanks.
Sergey Alexandrovich Kryukov at 17-Sep-12 21:21pm
   
None of the CLI types are equivalent the that, period. The type System.String is similar, but very, very remotely. String is a class, and LPWSTR is a disaster created long time ago, a source for million bugs stemmed from the totally stupid idea if having null-terminated strings. System.String can be marshaled as a number of C string types, that's it.
--SA
Andrewpeter at 17-Sep-12 22:40pm
   
Thanks you, SA. I'm going to study more about it. Can you comment with my topic: http://www.codeproject.com/Questions/460541/How-to-create-shortcut-using-WIN32API-in-Csharp. Thanks.
Sergey Alexandrovich Kryukov at 18-Sep-12 15:13pm
   
I answered it, as far as I could understand the question. Does it make sense to you?
--SA
Andrewpeter at 18-Sep-12 22:01pm
   
Thanks SA, your idea is useful for me.
Sergey Alexandrovich Kryukov at 18-Sep-12 22:32pm
   
Great. Good luck.
--SA
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 4

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.
  Permalink  
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

Try using Marshal.StringToHGlobalAnsi[^]
to convert managed string to unmanaged string (returns IntPtr pointing to converted string).
Then change import declaration to use IntPtr:
[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[^]
  Permalink  
v4
Comments
Andrewpeter at 17-Sep-12 10:38am
   
How will i call that function (in button1_Click() above). Thanks.
Andrewpeter at 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 at 17-Sep-12 11:28am
   
Take a look at url in updated solution.
It looks like Marshal.StringToCoTaskMemUni() should be used.
Andrewpeter at 17-Sep-12 11:41am
   
Thank you, I'll use it, my vote is 5 for your answer, thanks.
Philippe Mori at 23-Apr-13 22:53pm
   
You should specify mapping using attributes. See my solution.
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

Try this:
 
void CManagedClass::SetStr( String ^ theString ) {
     CUnmanagedClass m_Impl;
     pin_ptr<const WCHAR> str = PtrToStringChars(theString);
     m_Impl.SetString( str );
  }
  Permalink  
Comments
CHill60 at 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)

  Print Answers RSS
0 Sergey Alexandrovich Kryukov 464
1 CHill60 415
2 OriginalGriff 345
3 PIEBALDconsult 245
4 BillWoodruff 183


Advertise | Privacy | Mobile
Web03 | 2.8.141015.1 | Last Updated 23 Apr 2013
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100