views:

746

answers:

4

Hi When I want get total value of memory in C# I found a kernel32 function in MSDN to invoke data from system. MSDN declare function this way:

[return: MarshalAs(UnmanagedType.Bool)]
[DllImport("kernel32.dll", CharSet = CharSet.Auto, SetLastError = true)]
static extern bool GlobalMemoryStatusEx(ref MEMORYSTATUSEX lpBuffer);

but this don't work correctly. I change "ref" to "[In, Out]" then it work correctly. How can tell me what is [In, Out] parameters in C#?

+5  A: 

In: http://msdn.microsoft.com/de-de/library/system.runtime.interopservices.inattribute.aspx

Out: http://msdn.microsoft.com/de-de/library/system.runtime.interopservices.outattribute.aspx

Short: They control the way data is marshalled. In this case, where you specify both of them, it means that data is marshalled to both sides (caller and callee).

Maximilian Mayerl
ok, thanks. It's very very helpful. :)
Amir Borzoei
A: 

The out and the ref parameters are used to return values in the same variables, ref is enough if you don't know you will use it in or out.

Out if you just want to use the variable to receive data from the function, In if you just want to send data to the function.

ref if you want to send and receive data from a function, if you put nothing so it will be In by default

Note: ref and out parameters are very useful when your method needs to return more than one values.

Wael Dalloul
A: 

The following definition works (define the MEMORYSTATUSEX as a class):

[DllImport("kernel32.dll", SetLastError = true)]
[return: MarshalAs(UnmanagedType.Bool)]
public static extern bool GlobalMemoryStatusEx(MEMORYSTATUSEX lpBuffer);

[StructLayout(LayoutKind.Sequential)]
public sealed class MEMORYSTATUSEX {
  public uint dwLength = (uint)Marshal.SizeOf(typeof(MEMORYSTATUSEX));
  public uint dwMemoryLoad;
  public ulong ullTotalPhys;
  public ulong ullAvailPhys;
  public ulong ullTotalPageFile;
  public ulong ullAvailPageFile;
  public ulong ullTotalVirtual;
  public ulong ullAvailVirtual;
  public ulong ullAvailExtendedVirtual;
}

Usage

var status = new MEMORYSTATUSEX();
GlobalMemoryStatusEx(status);
Michael Damatov
A: 

If you look at the function definition on MSDN it will tell you whether the parameters are In/Out:

BOOL WINAPI GlobalMemoryStatusEx(
  __inout  LPMEMORYSTATUSEX lpBuffer
);

In general if it says out, you should use a ref parameter, it makes is easier on any future developers trying to figure out how the code is working. When looking at the function call, you know the developer meant for the argument to be affected.

scottm