views:

370

answers:

5

Hi friends,

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&lt;/LocURI&gt;&lt;/Target&gt;&lt;Source&gt;&lt;LocURI&gt;IMEI::358997011403172&lt;/LocURI&gt;&lt;LocName&gt;syncfdg&lt;/LocName&gt;&lt;/Source&gt;&lt;Meta&gt;&lt;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&lt;/LocURI&gt;&lt;/Target&gt;&lt;Source&gt;&lt;LocURI&gt;IMEI::358997011403172&lt;/LocURI&gt;&lt;LocName&gt;new123&lt;/LocName&gt;&lt;/Source&gt;&lt;Meta&gt;&lt;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>";
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;
A: 

seems the dll is a MFC extension dll, maybe only can be callec by MFC application. i am not sure.

Benny
A: 

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.

whunmr
A: 

use

System.Text.StringBuilder

pass that to your function

Tony
+1  A: 

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.

ctacke
HTTP SSL is not supported in WM6 and higher versions.
A: 

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);
Luke
That's not going to fix the mix of wide and multibyte in his C code.
ctacke
The mix doesn't really matter. HttpSendRequest is going to convert the Unicode headers to ANSI before sending them out. The post data is going to be passed through unmodified, and since it is already ANSI everything should be fine.
Luke