2009-12-21 37 views
0

我創建了一個win32 dll,它從我們的服務器發送和接收ssl數據包,我使用P/Invoke機制從我的C#應用​​程序調用了一個dll函數,該函數執行所有必要的任務。從C#應用程序調用win32 dll api

當我調用Connect(字符* lpPostData)

功能,我使用靜態字符POSTDATA []數組作爲帳請求它工作正常,如果我使用的char * lpPostData作爲發送參數從我的C#應用​​程序的發佈請求它不起作用。是否將C#字符串轉換爲char *?如果是這種情況,我該如何做?如何在Win32 dll中進行調試?

調用從C#應用程序導出的函數:

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

宣言是:

__declspec(dllexport) int Connect(char* lpPostData); 

的函數被定義爲:

__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></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; 
+4

親愛的主人,請溝碼/格式化/清潔/ SOMETHING – Will

+0

@unknown:我重新格式化您的代碼,以便它會顯示出來體面,但仍有在有人可以正確閱讀此文之前要完成工作。嘗試刪除不必要的混亂(註釋掉的行等) 考慮一下整個編碼器會更加一致的佈局,這些編碼器會在你後面出現。 –

+0

謝謝boris,我已經刪除了不必要的代碼。現在它很清楚。 – user160195

回答

0

似乎該DLL是一個MFC擴展DLL,也許只能由MFC應用程序進行收集。我不確定。

0

是否將C#字符串轉換爲char *?

.Net Interop Marshaler使用的默認CharSet是Ansi。

如果你想使用Unicode(LPCWSTR)參數, 你可以試試:

[DllImport("testdllwm6.dll", EntryPoint = "Connect", CharSet=CharSet.Unicode)] 
public static extern int pConnect(string postdata); 

順便說一句,你可以參考.Net 2.0 Interoperability Recipes: A Problem-Solution Approach 以獲取更多信息。

-1

使用

System.Text.StringBuilder

它傳遞給你的函數

1

故障點是非常明顯的。 Windows CE是Unicode。 C#中的字符串是一個寬字符數組,C中的char []是一個多字節。你在混合這兩個,這是壞的,壞的,壞的。

我的意思是你在同一個調用中混合它們,發送寬頭和多字節postData到HttpSendRequest?這當然是不對的。

更改連接功能看起來像這樣:

int Connect(TCHAR* lpPostData) 

再試一次,回來的結果。

當然這也意味着你也需要改變strlen調用。

作爲一個方面說明,我不明白爲什麼你會打電話到C++這個電話。你可以直接從你的C#應用​​程序中完成。

+0

WM6及更高版本不支持HTTP SSL。 – user160195

0

您需要將MarshalAs屬性添加到字符串參數中,以便.NET運行時知道如何封送它;默認字符串封送爲Unicode,但你要ANSI:

[DllImport("testdllwm6.dll", EntryPoint="Connect")] 
public static extern int Connect([MarshalAs(UnmanagedType.LPStr)] string lpPostData); 
+0

這不會在他的C代碼中修復寬和多字節的混合。 – ctacke

+0

混合並不重要。 HttpSendRequest在將Unicode標題發送出去之前將轉換爲ANSI。發佈數據將通過未經修改的方式傳遞,並且由於它已經是ANSI,所以一切都應該沒問題。 – Luke