2009-12-09 27 views
1

我使用wininet apis將HTTP POST發送到SSL服務器。我想使用P/Invoke將這些API包裝到C#中,因爲C#中的原始代碼。如何將這些API包裝到C#中。我嘗試過,但沒有奏效。我正在爲Windows Mobile和smatphones做這個。用於wininet API的P /調用機制

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; 

hInternet=InternetOpen(lpszAgent,INTERNET_OPEN_TYPE_PRECONFIG,NULL,INTERNET_INVALID_PORT_NUMBER,0); 
    if(!hInternet) 
{ 

    dwError = GetLastError(); 

} 

LPCTSTR lpszServerName = _T("mundusync"); 
INTERNET_PORT nServerPort =444; 
LPCTSTR lpszUserName = L""; 
LPCTSTR lpszPassword = L""; 
DWORD dwConnectFlags = 0; 
DWORD dwConnectContext = 0; 
DWORD dwCode = NULL; 
DWORD dwSize = 8000; 
char charBuffer[1000]; 
TCHAR szBuffer[1000]; 


int read = 0; 
char* str = "*/*", buff[1024] = {}; 



hConnect = InternetConnect(hInternet,L"s-syncml.geodesic.net", 
      nServerPort, 
      L"", 
      L"", 
      INTERNET_SERVICE_HTTP, 
      0, 
      0); 




    if(! hConnect) 
    { 


    dwError = GetLastError(); 

    } 


LPCWSTR lpszVerb = _T("POST"); 
LPCWSTR lpszObject = L"/"; 
LPCWSTR lpszVersion = NULL; 
LPCWSTR lpszReferer = NULL; 
LPCWSTR *lplpszAcceptTypes = NULL; 

DWORD dwFlags = INTERNET_FLAG_SECURE | 
      INTERNET_FLAG_IGNORE_CERT_CN_INVALID| 
      INTERNET_FLAG_IGNORE_CERT_DATE_INVALID; 

DWORD dwOpenRequestContext = 0; 

hRequest=HttpOpenRequest(hConnect,L"POST",L"/",HTTP_VERSION,L"",lplpszAcceptTypes,dwFlags,dwOpenRequestContext); 


if(!hRequest) 

{ 

    dwError = GetLastError(); 

} 




char lpPostData[637] ="<SyncML> some post data </SyncML>"; 

LPCWSTR lpszHeaders =_T("Content-Type: application/vnd.xyz+xml"); 
BOOL bResult; 
if(!HttpSendRequest(hRequest,lpszHeaders,wcslen(lpszHeaders),lpPostData,strlen(lpPostData))) 
{ 

    dwError = GetLastError(); 

} 

if (!(InternetQueryDataAvailable (hRequest, pSizeInResult, 0, 0))) 
    { 
     //wsprintf (dwError, TEXT("%s: %x"), TEXT("InternetQueryDataAvailableError"), GetLastError()); 
     return; 
     //WriteFile (hFile, szErrMsg, sizeToWrite, pSizeWritten, NULL); 
     //goto error; 
    } 

if (sizeInResult >= 1024) 
    { 
     int num = sizeInResult/1024; 

     do 
     { 
     //InternetReadFile (hRequest, lpBuffer, 1024, pSizeOutResult); 
      // WriteFile (hFile, lpBuffer, sizeOutResult, pSizeWritten, NULL); 
     } 
     while (--num > 0); 
    } 
    else 
    { 
     //InternetReadFile (hRequest, lpBuffer, sizeInResult, pSizeOutResult); 
     // WriteFile (hFile, lpBuffer, sizeOutResult, pSizeWritten, NULL); 

    do 
     { 
     // read from Internet HTTP server 
     if(InternetReadFile(hRequest, charBuffer, 
      1000, &dwRead)) 
     { 
      // convert to Unicode and display 
     charBuffer[dwRead] = '\0'; 
     mbstowcs(szBuffer, charBuffer, dwRead); 
     //cout « szBuffer; 
     szBuffer[dwRead] = '\0'; 
     } 


     } while(dwRead > 0); 

    } 

if(!hInternet) 
InternetCloseHandle(hInternet); 
if(!hConnect) 
InternetCloseHandle(hConnect); 
if(!hRequest) 
InternetCloseHandle(hRequest); 

回答

1

您應該檢查P/Invoke website。它們列出了衆所周知的DLL和「wininet」的所有P/Invoke定義。你也可以找到示例代碼。

1

如果你想重用你的本機代碼,你可以公開一個函數,它的服務器名稱和端口作爲輸入參數和返回數據讀取。這個本地函數可以再在C#中調用:

[DllImport("yourlib.dll")] 
static extern string FetchData(string host, int port); 

另一種選擇是使用.NET內置類來實現類似的功能:

var request = (HttpWebRequest)WebRequest.Create("http://s-syncml.geodesic.net:444"); 
request.UserAgent = "CeHttp"; 
var response = request.GetResponse(); 
using (var stream = response.GetResponseStream()) 
using (var reader = new StreamReader(stream)) 
{ 
    string result = reader.ReadToEnd(); 
}