Spence Green

التكرار يعلم الحمار

I work at Lilt. In addition to computers and languages, my interests include travel, running, and scuba diving. more...

Archive for the ‘.NET’ Category

Notifying Managed Code of a Native Callback

with 51 comments

Here’s a way for unmanaged code to notify managed code of a callback. The two code types use different calling conventions and the user cannot change the latter’s convention. Instead, use an inner class like this:

__gc classManagedClass
{
private:
__nogc class UnmanagedClass
{
static void __cdecl MyCallback()
{
ManagedClass *mc = ManagedClass::GetClass();
mc->MyFunc();
}
};

ManagedClass *thisClass;

public:
ManagedClass() { thisClass = this; }
static ManagedClass* GetClass() { return thisClass; }

void MyFunc() {}
};

The GetClass() method is a bit unsightly, but elegent nonetheless. The managed code can pass MyCallback to unmanaged code via a function pointer. The unmanaged code calls MyCallback and then MyCallback calls the managed method MyFunc(). This approach is especially useful for IJW DLLs in VC7.

References:

Written by Spence

July 8th, 2005 at 8:38 am

Posted in .NET

Managed Assemblies, IJW, and .h Files

without comments

I solved an intersting problem yesterday, although I still cannot fully explain the solution. My project uses a mixed mode DLL to load some native binaries. I constructed the DLL as a managed assembly so that in my managed code, I can use the following:

#using "mydll.dll"

This statement–It Just Works, or IJW–imports all types. Now I had defined my exception hierarchy in a separate header common to the whole project (not just the mixed dll). The exe and dll thus had the same #include statement. I could both compile and link with this setup. When the DLL threw an exception, though, I encountered a problem. Consider this snippet:


//Exception.h
__gc public MyException : public Exception
{
MyException(String *s) : Exception(s) {}
};

//mydll.dll, built with /LD /clr
#include "Exception.h"
myFunc() {
throw new MyException(S"BLAH");
}

//main.cpp, built with /clr
#include "Exception.h"
try
{
myFunc();
}
catch(MyException *e)
{
//This handler does not catch MyException!
}
catch(Exception *e)
{
Type *t = e->GetType();
Console::WriteLine(t->ToString());
}

The second exception handler illuminated the most elusive aspect of this issue. Although the first handler could not catch the exception, the second catch block showed a MyException type. I have not found a sufficient explanation for this behavior, but it must stem from the interaction of native code and MSIL in the mixed DLL.

Written by Spence

July 6th, 2005 at 7:54 am

Posted in .NET

Mixed Mode DLL and “/Zl”

with 581 comments

I spent 8 hours today debugging a stupid switch set by the VS.NET 2003 AppWizard. I’m trying to wrap some DLLs into a mixed mode DLL for use in some managed code. After laboring with an unmanaged wrapper compiled with /clr, I gave up and tried a “.NET Class Library” AppWizard. Then I added my DLLs, classes, etc. The project compiles correctly and then the linker fails, issuing this error:

LNK2020: unresolved token (0A00002C) ??_7type_info@@6B@

Right. I finally determined that the /Zl switch caused the issue. You will find this setting in Properties->C/C++->Command Line->Additional Options.

Mixed mode DLLs have significant issues in both .NET 1.0 and 1.1.

Written by Spence

June 30th, 2005 at 5:16 pm

Posted in .NET