UnmanagedType.LPStruct & INTERNET_BUFFERS

M

maxixi

Hi,

It is my first time to use C#, and i struggle with
my code with wininet api.

Declare API:
public abstract class WinInet
{
StructLayout(LayoutKind.Sequential)]
public struct INTERNET_BUFFERS
{
public UInt32 dwStructSize;
public IntPtr Next;
public String lpcszHeader;
public UInt32 dwHeadersLength;
public UInt32 dwHeadersTotal;
public byte[] lpvBuffer;
public UInt32 dwBufferLength;
public UInt32 dwBufferTotal;
public UInt32 dwOffsetLow;
public UInt32 dwOffsetHigh;
};

[DllImport("WinInet.dll",
EntryPoint="HttpSendRequestEx",
CallingConvention=CallingConvention.StdCall,
CharSet=CharSet.Auto,
SetLastError=true)]
public static extern UInt32 rawHttpSendRequestEx(
IntPtr hRequest,
[In, MarshalAs(UnmanagedType.LPStruct)] INTERNET_BUFFERS lpBuffersIn,
[Out, MarshalAs(UnmanagedType.LPStruct)] INTERNET_BUFFERS lpBuffersOut,
UInt32 dwFlags,
UInt32 dwContext);
....

Calling:

internal void DownloadThread()
{
WinInet.INTERNET_BUFFERS bi = new WinInet.INTERNET_BUFFERS();
WinInet.INTERNET_BUFFERS bo = new WinInet.INTERNET_BUFFERS();

uint sz = (uint)Marshal.SizeOf(typeof(WinInet.INTERNET_BUFFERS));
bi.dwStructSize = sz;
bo.dwStructSize = sz;

UInt32 ret = WinInet.rawHttpSendRequestEx(m_hRequest,
bi,
bo,
WinInet.HTTPSENDREQUEST.HSR_ASYNC,
3);

int err = Marshal.GetLastWin32Error();
....

The call of rawHttpSendRequestEx raise MarshalDirectiveException.
When i changed the buffer as
[In, MarshalAs(UnmanagedType.Struct)] INTERNET_BUFFERS lpBuffersIn,
[Out, MarshalAs(UnmanagedType.Struct)] INTERNET_BUFFERS lpBuffersOut,
the calling of rawHttpSendRequestEx failed (no exception)
and raise 87 error (GetLastError()).
The normal result of this code is (as in my VC6 code)
calling HttpSendRequestEx failed with 997 error (ERROR_IO_PENDING).

Whats wrong with my C# code?

Maxixi
 
M

Mattias Sjögren

public byte[] lpvBuffer;

This should be an IntPtr.

[In, MarshalAs(UnmanagedType.LPStruct)] INTERNET_BUFFERS lpBuffersIn,
[Out, MarshalAs(UnmanagedType.LPStruct)] INTERNET_BUFFERS lpBuffersOut,

You don't need the MarshalAs attribute here, but you have to make
these ref parameters.



Mattias
 
M

maxixi

I change my wininet declare, but one question

My VC code like this:
C++
INTERNET_BUFFERS BufferIn;
memset(&BufferIn, 0, sizeof(INTERNET_BUFFERS));
BufferIn.dwStructSize = sizeof(INTERNET_BUFFERS);

BufferIn.lpvBuffer = (void*)m_sFormPostData.c_str();
BufferIn.dwBufferTotal = BufferIn.dwBufferLength =
m_sFormPostData.length();

ResetContext();
if (!HttpSendRequestEx(hInternet, &BufferIn, NULL, <--null param
HSR_ASYNC, (DWORD)pContext)) {
if (GetLastError() != ERROR_IO_PENDING) {
ret = 1;
goto err;
}

How to change the 3rd param with NULL in C#?
UInt32 ret = WinInet.rawHttpSendRequestEx(m_hRequest,
ref bi,
null, <-- Compiler say error!
WinInet.HTTPSENDREQUEST.HSR_ASYNC,
3);

I can not use null as the parameter!

How to
Mattias Sjögren said:
public byte[] lpvBuffer;

This should be an IntPtr.

[In, MarshalAs(UnmanagedType.LPStruct)] INTERNET_BUFFERS lpBuffersIn,
[Out, MarshalAs(UnmanagedType.LPStruct)] INTERNET_BUFFERS
lpBuffersOut,

You don't need the MarshalAs attribute here, but you have to make
these ref parameters.



Mattias
 
M

Mattias Sjögren

If you want to pass NULL you can change the parameter to IntPtr (by
value) and use IntPtr.Zero as the argument.



Mattias
 
M

maxixi

I can declare INTERNET_BUFFERS as class
and pass the null to bufferin & bufferout

Thanks Mattias Sjögren
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top