Wininet API的P / Invoke机制

时间:2009-12-09 09:46:48

标签: windows windows-mobile

我使用wininet apis将HTTP POST发送到SSL服务器。我想使用P / Invoke将这些api包装到C#,因为C#中的原始代码。我如何将这些api包装到c#中。我试过但它没有奏效。我正在为Windows mobile和smatphones做这个。

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);

2 个答案:

答案 0 :(得分:2)

您应该查看P/Invoke website。它们列出了众所周知的DLL的所有P / Invoke定义,特别是“wininet”。您还可以找到示例代码。

答案 1 :(得分: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();
}