Groups | Blog | Home
all groups > dotnet interop > may 2006 >

dotnet interop : Tool Help API and interop (C#)


ziphnor NO[at]SPAM gmail.com
5/26/2006 2:06:45 AM
Hi,

I am trying to call the Tool Help API (
http://msdn.microsoft.com/library/default.asp?url=/library/en-us/perfmon/base/tool_help_functions.asp
) from C# using interop.

I have declared:

[DllImport("Kernel32.dll")]
private static extern IntPtr CreateToolhelp32Snapshot(UInt32
dwFlags, UInt32 th32ProcessID);

[DllImport("Kernel32.dll")]
private static extern bool Thread32First(IntPtr hSnapshot, ref
THREADENTRY32 lpte);


The THREADENTRY32 struct is declared as:

[StructLayout(LayoutKind.Sequential)]
public class THREADENTRY32
{
public UInt32 dwSize;
public UInt32 cntUsage;
public UInt32 th32ThreadID;
public UInt32 th32OwnerProcessID;
public Int32 tpBasePri;
public Int32 tpDeltaPri;
public UInt32 dwFlags;
}

On the C side its:
typedef struct tagTHREADENTRY32 {
DWORD dwSize;
DWORD cntUsage;
DWORD th32ThreadID;
DWORD th32OwnerProcessID;
LONG tpBasePri;
LONG tpDeltaPri;
DWORD dwFlags;
} THREADENTRY32,
*PTHREADENTRY32;

I call CreateToolhelp32Snapshot with the current process ID and
TH32CS_SNAPTHREAD (=0x4) and get something which appears correct(ie the
handle returned is not equal to INVALID_HANDLE_VALUE(=-1) and
GetLastError returns 0).

However when i then call:
THREADENTRY32 te = new THREADENTRY32();
Int32 size =
System.Runtime.InteropServices.Marshal.SizeOf(te);
te.dwSize = (uint)size;
bool ok = Thread32First(h, ref te); // h is return value of
CreateToolhelp32Snapshot

ok is false and GetLastError is 24 which translates to:
ERROR_BAD_LENGTH ("The program issued a command but the command length
is incorrect.").

Im guessing something is wrong with the struct i am passing in, but
what? I have checked that dwSize is set to 28 which is correct as far
as i can tell. Any help is appreciated.
Mattias Sjögren
5/26/2006 8:09:59 PM

[quoted text, click to view]

Don't call GetLastError from managed code. Add SetLastError=true to
the dllImport attribute and then call Marshal.GetLastWin32Error
instead.


[quoted text, click to view]

It's a class, not a struct. That's the problem. Change it to a struct,
or remove the ref modifier on the parameter.


Mattias

--
Mattias Sjögren [C# MVP] mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
ziphnor NO[at]SPAM gmail.com
5/27/2006 2:04:46 PM
[quoted text, click to view]

I feel like an idiot :) This solved the problem, thanks.
AddThis Social Bookmark Button