16 December 2008

Determine the layout of a structure for .Net Platform Invoke

I was trying to create a signature for NOTIFYICONDATA, and decided to see what I could find out about it with C++.

1) start a new c++ CLR Console project in visual studio. Name it whatever you like. 2) Alter stdafx.h:

#pragma once
#define STRICT
#include <windows.h>   // common Win32 stuff
#include <commctrl.h>  // defines the structure we are interseted in
#include <stddef.h>    // we use offsetof
using namespace System;  // .Net types

3) in main, you can create a structure and determine its size. You can also find the offset for each field in the structure. Then you can swap the build to x64 and see what size they should be on x64 systems. This is definitely useful for when you want to create a managed C# or VB.Net version of the structure.

#include "stdafx.h"

using namespace System;

int main(array<System::String ^> ^args)
{
    NOTIFYICONDATA tbb;
    int i = sizeof(tbb);
    Console::WriteLine(i);   
    Console::WriteLine(offsetof(NOTIFYICONDATA,cbSize));
    Console::WriteLine(offsetof(NOTIFYICONDATA,hWnd));
    Console::WriteLine(offsetof(NOTIFYICONDATA,uID));
    Console::WriteLine(offsetof(NOTIFYICONDATA,uFlags));
    Console::WriteLine(offsetof(NOTIFYICONDATA,uCallbackMessage));
    Console::WriteLine(offsetof(NOTIFYICONDATA,hIcon));
    Console::WriteLine(offsetof(NOTIFYICONDATA,szTip));
    Console::WriteLine(offsetof(NOTIFYICONDATA,dwState));
    Console::WriteLine(offsetof(NOTIFYICONDATA,dwStateMask));
    Console::WriteLine(offsetof(NOTIFYICONDATA,szInfo));
    Console::WriteLine(offsetof(NOTIFYICONDATA,uTimeout));
    Console::WriteLine(offsetof(NOTIFYICONDATA,szInfoTitle));
    Console::WriteLine(offsetof(NOTIFYICONDATA,dwInfoFlags));
    Console::WriteLine(offsetof(NOTIFYICONDATA,guidItem));
    Console::WriteLine(offsetof(NOTIFYICONDATA,hBalloonIcon));
    Console::ReadKey();
    return 0;
}
Ugly, but it works.

No comments:

Post a Comment