Pocket PC Forum / Developers / Windows Mobile / March 2006
return value from c dll to c# - missing chars
|
|
Thread rating:  |
Simon - 06 Jan 2006 08:53 GMT Hi
I have written a DLL in eVC4 and exported a function that returns a value. I have told the DLL to message box the results before returning, and this shows what I expect, in the example code below its "123456789". When it returns to c# I again message box the result which shows "56789". Any help would be greatly appreciated.
c++ code extern "C" { __declspec(dllexport)LPTSTR testreturn() {
LPTSTR test; test = L"123456789"; MessageBox(NULL, test, L"TEST", MB_OK); return test;
}
}
c# code
[DllImport("test.dll", EntryPoint = "testreturn")] public static extern string testreturn();
string h = testreturn(); MessageBox.Show(h , "TEST c#");
<ctacke/> - 06 Jan 2006 13:07 GMT It's not a good idea to return a string pointer from a native function, as the memory pointed to is owned by the callee, not the caller.
Try this:
extern "C" { __declspec(dllexport)void testreturn(TCHAR *data) { _tcscpy(data, _T("123456789")); }
}
c# code
[DllImport("test.dll", EntryPoint = "testreturn")] public static extern void testreturn(StringBuilder sb);
StringBuilder sb = new StringBuilder(1024); testreturn(sb); MessageBox.Show(sb.ToString());
-Chris
> Hi > [quoted text clipped - 29 lines] > string h = testreturn(); > MessageBox.Show(h , "TEST c#"); Simon - 06 Jan 2006 14:00 GMT Cheers Chris works a treat
> It's not a good idea to return a string pointer from a native function, as > the memory pointed to is owned by the callee, not the caller. [quoted text clipped - 54 lines] > > string h = testreturn(); > > MessageBox.Show(h , "TEST c#"); MSenne - 06 Jan 2006 14:31 GMT Just as an aside, you should be sure to use StringBuilder when dealing with character string pointers (ie. if you want to get a string back from your native Dll call). Using a 'string' object doesn't do the job. And be sure to initialize your StringBuilder with sufficient length or it won't go as planned.
Lochan Pandya - 24 Mar 2006 13:32 GMT Hi Cris/simon, Well I too tried to do the same thing but in a different way. I want to transfer a string from c# to eVC++.
c# code :
[DllImport("CryptoUtil.dll")] private static extern int fnDecryptPayload(StringBuilder sb);
StringBuilder sb1 = new StringBuilder(strTokenKeyFile.Length); sb1.Append(strTokenKeyFile)
int CharsReturned = fnDecryptPayload(sb1);
c++ code:
DECRYPTPAYLOAD_API long fnDecryptPayload(TCHAR * tokenFile)
But if I print the "tokenfile" string in c++ i get exactly the half of string that I send from c#.
Please help.
Thanks, Lochan.
> Cheers Chris works a treat > [quoted text clipped - 56 lines] > > > string h = testreturn(); > > > MessageBox.Show(h , "TEST c#"); Chris Tacke [MVP] - 24 Mar 2006 19:30 GMT Show us the code you're using to print the data in C++.
-Chris
> Hi Cris/simon, > Well I too tried to do the same thing but in a different way. [quoted text clipped - 87 lines] >> > > string h = testreturn(); >> > > MessageBox.Show(h , "TEST c#"); Lochan Pandya - 27 Mar 2006 08:08 GMT First of all, thanx for brisk reply chris.
My C++ code:
DECRYPTPAYLOAD_API long fnDecryptPayload(TCHAR * tokenFile) { HANDLE hlochan = 0; DWORD dwRetSize = 0; hlochan = CreateFile(L"c:\\lochan.txt",GENERIC_WRITE,0,0,CREATE_ALWAYS,0,0); WriteFile(hlochan,tokenFile,wcslen(tokenFile),&dwRetSize,NULL); if(hlochan != 0) { CloseHandle(hlochan); } }
In c++: I am trying to write the string variable "tokenFile" in the file lochan.txt
In C#: In the variable "tokenFile" i'll pass the token file's absolute path eg. "c:\\windows\\token.clear"
Thanks, Lochan
> Show us the code you're using to print the data in C++. > [quoted text clipped - 91 lines] > >> > > string h = testreturn(); > >> > > MessageBox.Show(h , "TEST c#"); <ctacke/> - 27 Mar 2006 14:03 GMT 1. CE has no concept of drives, so "C:\{anything}" is meaningless. 2. Don't mix your macros, if you use TCHAR, use _tcslen, not wcslen. If you compile that under ANSI it will break. 3. WriteFile takes a number of bytes to write, not a number of characters. Since under unicode TCHAR is 2 bytes per character, your wcslen will return 1/2 the number of bytes in the string, and won't account for a terminating null.
Should be something like this:
WriteFile(hlochan, tokenFile, (_tcslen(tokenFile) + 1) * sizeof(TCHAR), &dwRetSize, NULL);
-Chris
> First of all, thanx for brisk reply chris. > [quoted text clipped - 122 lines] >> >> > > string h = testreturn(); >> >> > > MessageBox.Show(h , "TEST c#"); Lochan Pandya - 28 Mar 2006 12:17 GMT Chris, I use: # include <tchar.h>
changed the WriteFile to:
WriteFile(hlochan,tokenFile,(_tcslen(tokenFile) + 1)* sizeof(TCHAR),&dwRetSize,NULL);
I get the error while compiling : error C2664: 'strlen' : cannot convert l from 'TCHAR *' to 'const char *'
If I use WCHAR instead of TCHAR, this is what I do:
WriteFile(hlochan,tokenFile,(wcslen(tokenFile))* sizeof(WCHAR), &dwRetSize,NULL);
I am getting the string but i think the string end is not interpreted properly. If I give the same string c:\\token.clear, it is transported with three spaces appended to it. If I send string c:\\lochan\\token.clear i get the strange string : "㩃屜潬档湡屜潴敫汣慥rWS/Microsoft.NET/Framework/v1.1.4322/System.dll"
Actually first I am testing this application on my desktop and then will try it on my PDA.
Thanks, Lochan
> 1. CE has no concept of drives, so "C:\{anything}" is meaningless. > 2. Don't mix your macros, if you use TCHAR, use _tcslen, not wcslen. If you [quoted text clipped - 137 lines] > >> >> > > string h = testreturn(); > >> >> > > MessageBox.Show(h , "TEST c#");
|
|
|