calling win32 dll api from C# application
I have created a win32 dll which sends and recieves ssl data packets from our server, I am calling a dll function using P/Invoke mechanism from my C# app which does all necessary tasks.
When I call Connect(char* lpPostData)
function and I use static char postData [] array as a posting request it works fine , if I use char* lpPostData as sent parameter from my C# app for posting request it doesn't works. Is it something with conversion of C# string to char * ?? if that is the case how do i do it ?? How to debug the in Win32 dll ???
Calling the exported function from C# app:
[DllImport("testdllwm6.dll", EntryPoint = "Connect")] public
static extern int pConnect(string postdata);
string postdata="<SyncML><SyncHdr><VerDTD>1.2</VerDTD><VerProto>SyncML/1.2</VerProto><SessionID>33622878</SessionID><MsgID>1</MsgID><Target><LocURI>http://sync.com</LocURI></Target><Source><LocURI>IMEI::358997011403172</LocURI><LocName>syncfdg</LocName></Source><Meta><MaxMsgSize
xmlns=\"syncml:metinf\">10000</MaxMsgSize></Meta></SyncHdr><SyncBody><Alert><CmdID>1</CmdID><Data>201</Data><Item><Target><LocURI>contacts</LocURI></Target><Source><LocURI>./contacts</LocURI></Source><Meta><Anchor
xmlns=\"syncml:metinf\"><Last>000000T000000Z</Last><Next>20091125T122400Z</Next></Anchor></Meta></Item></Alert><Final></Final></SyncBody></SyncML>";
int j = pConnect(postdata);
Declaration is:
__declspec(dllexport) int Connect(char* lpPostData);
The function is defined as:
__declspec(dllexport) int Connect(char* lpPostData) {
LPCTSTR lpszAgent = _T("CeHttp");
DWORD dwError; DWORD sizeInResult,
sizeOutResult, sizeToWrite,
sizeWritten,dwRead; HINTERNET
hInternet=NULL; HINTERNET
hConnect=NULL; HINTERNET
hRequest=NULL; LPDWORD
pSizeInResult = &sizeInResult;
LPDWORD pSizeOutResult = &sizeOutResult;
LPDWORD pSizeToWrite = &sizeToWrite;
LPDWORD pSizeWritten = &sizeWritten; int read = 0;
char postData[637]
="<SyncML><SyncHdr><VerDTD>1.2</VerDTD><VerProto>SyncML/1.2</VerProto><SessionID>66622878</SessionID><MsgID>1</MsgID><Target><LocURI>http://sync.com</LocURI></Target><Source><LocURI>IMEI::358997011403172</LocURI><LocName>new123</LocName></Source><Meta><MaxMsgSize
xmlns=\"syncml:metinf\">10000</MaxMsgSize></Meta></SyncHdr><SyncBody><Alert><CmdID>1</CmdID><Data>201</Data><Item><Target><LocURI>contacts</LocURI></Target><Source><LocURI>./contacts</LocURI></Source><Meta><Anchor
xmlns=\"syncml:metinf\"><Last>000000T000000Z</Last><Next>20091125T122400Z</Next开发者_如何学Go></Anchor></Meta></Item></Alert><Final></Final></SyncBody></SyncML>";
LPCWSTR lpszHeaders =_T("Content-Type: application/vnd.sync+xml");
BOOL bResult;
if(!HttpSendRequest(hRequest,lpszHeaders,wcslen(lpszHeaders),
lpPostData,strlen(lpPostData)))
{
dwError = GetLastError();
printf(" not HttpSendRequest");
return read;
}
return read;
The failure point is very obvious. Windows CE is Unicode. The string in C# is a wide-character array, the char[] in C is a multibyte. You're mixing the two, and that is bad, bad, bad.
I mean you're mixing them in the same call, sending wide headers and multibyte postData to HttpSendRequest? That certainly can't be right.
Change the Connect function to look like this:
int Connect(TCHAR* lpPostData)
try it again, and come back with the results.
Of course this also means you need to change the strlen call as well.
As a side note, I don't understand why you would call into C++ for this call anyway. You could do it right from your C# app.
seems the dll is a MFC extension dll, maybe only can be callec by MFC application. i am not sure.
Is it something with conversion of C# string to char * ??
The default CharSet used by the .Net Interop Marshaler is Ansi.
If you want use Unicode(LPCWSTR) parameters, you can try:
[DllImport("testdllwm6.dll", EntryPoint = "Connect", CharSet=CharSet.Unicode)]
public static extern int pConnect(string postdata);
BTW, you can refer to .Net 2.0 Interoperability Recipes: A Problem-Solution Approach for more information.
You need to add the MarshalAs attribute to the string parameter so the .NET runtime knows how to marshal it; by default strings are marshaled as Unicode, but you want ANSI:
[DllImport("testdllwm6.dll", EntryPoint="Connect")]
public static extern int Connect([MarshalAs(UnmanagedType.LPStr)] string lpPostData);
use
System.Text.StringBuilder
pass that to your function
精彩评论