我创建了一个win32 dll,它从我们的服务器发送和接收ssl数据包,我正在使用来自我的C#app的P / Invoke机制调用一个dll函数,它执行所有必要的任务。
当我调用Connect(char * lpPostData)
时函数和我使用静态char postData []数组作为发布请求它工作正常,如果我使用char * lpPostData作为我的C#app的发送参数发布请求它不起作用。是否将C#字符串转换为char *?如果是这样的话我该怎么做?如何调试Win32 dll ???
从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);
声明是:
__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;
答案 0 :(得分:1)
失败点非常明显。 Windows CE是Unicode。 C#中的字符串是宽字符数组,C中的char []是多字节数组。你把两者混合在一起,那就是坏,坏,坏。
我的意思是你在同一个调用中混合它们,向HttpSendRequest发送宽标头和多字节postData?这肯定是不对的。
将Connect功能更改为如下所示:
int Connect(TCHAR* lpPostData)
再试一次,然后回来看结果。
当然这也意味着您还需要更改strlen调用。
作为旁注,我不明白你为什么要为这个电话打电话给C ++。你可以直接从你的C#应用程序中完成。
答案 1 :(得分:0)
似乎dll是MFC扩展dll,也许只能通过MFC应用程序进行callec。我不确定。
答案 2 :(得分: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);
BTW,你可以参考.Net 2.0 Interoperability Recipes: A Problem-Solution Approach 了解更多信息。
答案 3 :(得分:0)
您需要将MarshalAs属性添加到字符串参数中,以便.NET运行时知道如何编组它;默认情况下,字符串被编组为Unicode,但您需要ANSI:
[DllImport("testdllwm6.dll", EntryPoint="Connect")]
public static extern int Connect([MarshalAs(UnmanagedType.LPStr)] string lpPostData);
答案 4 :(得分:-1)
使用
System.Text.StringBuilder
将其传递给您的函数