Slimdx

November 18, 2009

I’ve been working on some graphics work using SlimDx. I really like the library but the documentation is sparse in some places


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
{
    ///...
public:
    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);

    SetCallBackInNativeFunction((SomeCallbackType)ptr2Func.ToPointer());
}

 

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

[UnmanagedFunctionPointer(CallingConvention::Cdecl)]
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.

image

Brought to you via here.

 

sidenote:

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.


Finally …

February 28, 2008

… some respite. The project I was working was finally demo’ed today. It was successful. I’m on the demo high right now, but I think I will have some more time to blog about other topics. My next project is to find a nice thunking library to convert C++ member functions so that they can be passed to a function that has a pointer to a C function.


Using Boost::Bind and Boost::Function for Windows Procedure Functions

February 25, 2008

The experiment failed. What was I thinking? I forgot that C++ member functions have an implicit this pointer, that makes them pretty useless as function pointers. Oh well… Onto finding a good thunking library … Who woulda thunk?


Installing the Visual Studio Express Editions

February 12, 2008

I’m installing the express editions right now. As much as I like the environment, I’m just not willing to fork over $200+ for the standard edition. If it works, Great!! Otherwise not so great, and I will cough up the money. That $600 rebate might have come in handy right now.


I need a TypeLib viewer

January 22, 2008

Ever since I moved from Visual C++ 6.0 I’ve missed OleView. OleView was released as a sample and continued to work under Windows XP. Under Vista however, everytime I double click on something to read the type library, the application freezes up and goes into an infinite loop. I’ve tried debugging it but due to some laziness on my part and a new idea that’s been forming in my head for some time, I haven’t been able to solve it yet.

Besides there are many other things that are wrong with OleView. OleView relies exclusively for the registry, which really slows it down while it traverses the registry. With Side By Side installation, a theoretical type library viewer should be able to access the type information directly from the component itself, and should the user so desire traverse the registry.