An Adventure in Function Pointers, Delegates, and Calling Conventions

March 12, 2008

I’ve been interfacing a third-party library for a project at work. The third party library is a DLL with a C interface. Now most libraries for Windows usually have  a __stdcall calling conventions and for some reason I assumed that would be case with the C library. I guess it was because the demo application had  not done anything to give a hint otherwise. Since the client component was going to be in .net component, I wrote a nice little C++/CLI wrapper around the unmanaged native library, so that I could easily call it from C#. I decided against using P/Invoke because I don’t like using meta-information in source code to identify implementation of interfaces. In my opinion using P/Invoke client code too dependent on a specific library. That’s a topic for another post.

One of the functions of the library needed a function pointer to a callback function. The prototype of the function was something like this, wrapped with linkage.

extern "C"
    typedef void (*SomeCallbackType)(int, char*, float);
    void SetCallBackInNativeFunction(SomeCallbackType p){/*...*/}

Since I wanted the callback mechanism to hook up to .Net delegates I did something as follows,

using namespace System;
using namespace System::Runtime::InteropServices;

delegate void FooDelegate(int arg1, char* arg2, float arg3);

ref class AClass
    void FooCallback(int arg1, char *arg2, float arg3){/*...*/}

static GCHandle globalGCHandle;

void SetCallback()
    AClass ^theObj = gcnew AClass();
    FooDelegate ^del = gcnew FooDelegate(theObj, &AClass::FooCallback);
    //We want to do this because the callback will be called many times. 
    //and may live through many garbage collection sprees.
    //This would be freed at the end of the program. 
    globalGCHandle = GCHandle::Alloc(del); 

    IntPtr ptr2Func = Marshal::GetFunctionPointerForDelegate(del);



Now every time time I ran my program, it would start up normally, but then mysteriously crash with really exceptions like 0xC00005, 0xC0000013, etc. I recognized these exceptions that indicated access violation and stack corruption exceptions. I turned on exception handlers in the debugger but the debugger refused to catch those exceptions. I was mystified. I thought that the exceptions were happening because the garbage collector was moving around my delegate, which is why  I used the globalGCHandle = GCHandle::Alloc(del). That didn’t help. Turned out the program was crashing because Marshal::GetFunctionPointerForDelegate returns a function pointer with __stdcall calling convention. Now as everyone knows __stdcall and __cdecl (the default in C compilers) are incompatible, and it causes really confusing errors because the somehow or the other the stack always ends up corrupted. The compiler (at least VC compiler) would have helped had I been passing a native function pointer. With managed code, the compiler happily let me shoot myself in the foot. The solution was to add the following attribute to delegate declaration

delegate void FooDelegate(int arg1, char* arg2, float arg3);

which I got from here

The program worked flawlessly after that (I mean it did what I wanted it to do).



IronPython and/or F#

March 11, 2008

I’ve been working with a large project that has a lot of unmanaged MFC and C++ code, and new managed code using C#, C++/CLI with a many third-party libraries written in unmanaged code. Because of the complexity of the code, and sheer number of projects (>50 at the last count), I’ve been debating on using some scripting language to prototype and test code. I know Python, so I’ve started off with that. Unfortunately, Visual Studio 2005 does not have a good integration with the IronPython console. I tried getting the add-in sample to integrate with Visual Studio, but after wasting a few hours decided to use it without intellisense.

F# on the other hand has pretty good integration wit a REPL console, compiler and interpreter. Although, I know some functional programming,  (doing some programming in Lisp, Haskell, and Boost.(Lambda|Bind|Spirit) in C++), F# seems to have an alien syntax. I’m pretty sure that after a few hours, I should get the hang of it. Probably, next weekend. Although its looking more and more likely that I’ll be at work this weekend again.

I do like this T-shirt though.


Brought to you via here.



I wish plain old C enums played nicely with CLS enums, or that I was smart enough to remember the nuances of how they differ.

2008 Tipperary Hill Shamrock Run « Race Time Results

March 10, 2008

 2008 Tipperary Hill Shamrock Run « Bit By Bit, Byte by Byte, Word by Word

Gun Place 588
Gun Time 37:59
Gun Pace 9:30
Net Place 593
Net Time 37:18
Net Pace 9:20

2008 Tipperary Hill Shamrock Run

March 7, 2008

Running this race tomorrow morning. Its pretty nasty outside today. In fact there is a winter snow storm warning till Sunday evening. Wish me luck.

2008 Tipperary Hill Shamrock Run

Need a crash course in probability

March 1, 2008

… (again)