Tomer Gabel's annoying spot on the 'net RSS 2.0
# Tuesday, January 9, 2007

I've been hacking away quite a bit at an application that contains large managed and unmanaged portions, and a necessarily complex interop layer in between. It appears that interop marshalling behaves somewhat differently between the full and Compact framework. Here's a somewhat laconic list of the issues I've encountered and how to resolve them:

  1. You may encounter NotSupportedException on calls to Marshall.SizeOf. Although the documentation does not specify this as a possible exception, experience shows that this is a result of wrong marshalling attributes: for example, although trying to marshal a bool to UnmanagedType.I4 makes sense from a C programmer's perspective, it results in the behavior described above. The article describing this is called "Using the MarshalAsAttribute Attribute," but the version in my locally installed copy of MSDN Library (August 2006) does not contain this information.
  2. Annoyingly, the default marshalling, or even an explicit UnmanagedType.Bool, results in corrupt values (probably some minor framework bug). I worked around this by defining the member as int and manually giving it the value 0 or -1.
  3. It's not obvious, but you can't use UnmanagedType.LPArray from within structures - it only works on P/Invoke method declaration parameters. The only way to do this is to manually call Marshal.StructureToPtr and do some pointer arithmetic with IntPtr (annoying, but at least it's safe code).
  4. The marshaller always frees up memory; although this makes a lot of sense from the .NET perspective, it probably means that you'll have to code in some sort of deep copying mechanism in your native code if you want any of that information in your state. This also has performance repercussions you should consider when architecting your interop layer.

I'll post updates to this as I come across more issues.

Tuesday, January 9, 2007 6:34:43 PM (Jerusalem Standard Time, UTC+02:00)  #    -
Development | Compact Framework
# Sunday, January 7, 2007

I was writing some code with Visual Studio 2005, and pressed Alt+Keypad 8 (under ReSharper, this moves the current method up/down). Not only did this produce the ASCII code 8 - backspace (control character) or inverse bullet (printable character) - but it also completely screwed up the font on the same line:

Sunday, January 7, 2007 7:45:26 PM (Jerusalem Standard Time, UTC+02:00)  #    -
Development
# Thursday, January 4, 2007

For some reason the Visual Studio 2005 debugger (on my native Smart Device project) flat out refused to halt on Data Abort errors. Instead it would just show the error information on the debug trace and crash the application: 

Data Abort: Thread=81e27040 Proc=804c68c0 'Client.exe'
AKY=00000041 PC=00eb1cc0(emnative.dll+0x00001cc0) RA=00eb6d6c(emnative.dll+0x00006d6c) BVA=0e537510 FSR=00000007

For obvious reasons, I wasn't particularly happy with this. Digging into Google and the documentation didn't help; after some serious headscratching I figured that the Windows CE kernel must be catching these exceptions at some point, so from the Debug->Exceptions... menu I enabled, under Win32 Exceptions, catching of thrown Access Violations:

After this, I managed to finally get proper trapping in the debugger, and easily find out what code actually caused the access violation:

 

Thursday, January 4, 2007 5:50:12 PM (Jerusalem Standard Time, UTC+02:00)  #    -
Development | Compact Framework
# Tuesday, January 2, 2007

Robbie Williams plays an amazing comedian turned president in Man of the Year. The movie is a non-too-small jab at American democracy, the American democratic process and the American voting public in general. As such it's inevitably cynical, however it still manages to temper cynicism with a genuine attempt to make people see that the democratic process is not completely rotten, that things people take for granted are the result of a lot of hard-work by a lot of usually well-meaning people, and finally reiterates the old adage to "never attribute to malice that which is adequately explained by stupidity."

Otherwise, it's a well-directed, well-acted (featuring, among others, Christopher Walken, Laura Linney and Jeff Goldbloom) and well-written movie. Recommended.

Tuesday, January 2, 2007 3:53:49 PM (Jerusalem Standard Time, UTC+02:00)  #    -
Movies
# Monday, December 25, 2006

This is an absolute must-read for anyone who gives even a bit of a damn about their rights as consumers. (via Aynde)

My brother thinks it's basically FUD-based propaganda, but I suppose if it's a way to make people listen it works for me (when fighting fair just isn't enough...)

Update (02-Jan-2007): Read this rebuttal. It's extremely cynical, but also makes several valid points.

Update (03-Jan-2007): For a more cynical and consumer-oriented view, check out this scathing editorial from The Inquirer. It's amazing how much it echoes my thoughts - as a consumer - on the subject. I wrote a few sentences about the subject before I realized it deserved a proper post, which I'll handle later this week.


Monday, December 25, 2006 2:59:47 PM (Jerusalem Standard Time, UTC+02:00)  #    -
Personal | Software

It really yanks my chain when I put my faith into what is presumably a solid foundation for my code, and end up running into a huge number of unexpected pitfalls.

Be warned: .NET Compact Framework is incomplete. Oh yes, it's a fleshed out version of CF 1.0 with generics and various important bits and pieces finally included (COM interop. I mean, seriously, .NET is useless without it even on the desktop), but it's still lacking a lot of vital components (ActiveX hosting) and has major shortcomings in others (no XSLT support). But that isn't the worst of it: the documentation is sparse at best, and flat out wrong in some cases.

You cannot use asynchronous delegates in .NET CF 2.0.

In case it isn't clear to you, let me repeat it: you can't use Delegate.BeginInvoke. If you're really unlucky, like me, you'll write a bunch of code and go on to compile, run, test and debug it and then run into a completely bogus NotSupportedException on a seemingly innocuous internal method call, and have to do some serious digging to figure out the culprit. This goes particularly well with (admittedly documented) fineprint in methods such as Windows Media Player's player.URL property setter, which for some reason mustn't be called from an event handler.

Monday, December 25, 2006 3:59:25 AM (Jerusalem Standard Time, UTC+02:00)  #    -
Development | Compact Framework
# Tuesday, December 19, 2006

I've blogged about Neil Gaiman's MirrorMask before, and have neglected to follow up with comments on the movie. To make it short and to the point: it's brilliant. Original story (Alice-esque, but is otherwise new and fascinating), amazing artwork, impressive photography, great music and terrific acting. This is a top-notch movie which in many ways is better than Labyrinth, and easily parallels Dark City in imagination and visual production. Although this is not a movie for everyone, I would greatly recommend it to anyone who's enjoyed the above movies, or for that matter Lemony Snicket's A Series of Unfortunate Events.

A completely different beast is Borat (I'll spare you the full title). Anyone who's ever watched Ali G should already be familiar with how hysterically sad this character is; it's not that Borat as a character is funny, it's just how stupid the people he interviews are. To put it mildly, it was difficult getting up when the movie ended because my stomach muscles were so sore from laughing. And Borat speaks Hebrew almost the whole movie, to boot!
(Disclaimer: it's worth noting that this movie is completely idiotic, full of profanity and racist jokes. If you're touchy enough to be bothered by this, you shouldn't be reading this blog.)

I won't deny being an Alfonso Cuarón fan; although I've only seen two of his movies, they both impressed me by being completely original and visually striking. His newest movie, Children of Men, definitely struck a chord with me. I'm not sure if this is obvious to anyone but me, but the narrative is like a modernized version of War of the Worlds with a human emphasis (i.e. no aliens): a regular joe getting caught in turbulent times, just one amazing thread of story that appears meaningless when viewed in the grand scheme of things. I'm not a professional writer so it's difficult for me to explain this properly - I hope I've managed to at least pique your curiosity.

Finally, I just feel the need to share a bunch of anecdotes:

  • The Princess Bride is still (after so many years) a masterpiece of duality: sentimentality and criticism, virtue and wickedness, beauty and hardship. It's simply a brilliant tale, and if you haven't seen the movie you literally owe it to yourself.
  • Holy shite, they're making a new Beowulf movie! One directed by Robert Zemeckis and written by Neil Gaiman no less. Who knows, maybe it won't utterly suck?
  • They're actually making new Rocky and Rambo movies. Rocky 5000 all over again?... I mean, I like Sly as much as the next guy, but he's over 60!
  • Pan's Labyrinth looks really gorgeous. The visual style is starting to get old, but the movie itself looks incredibly promising, and I'm definitely looking forward to it.
Tuesday, December 19, 2006 6:11:35 PM (Jerusalem Standard Time, UTC+02:00)  #    -
Movies

Update (January 16th, 2007): Not only does this apparently only work on the emulator, you would do well to stay away from Managed DirectX in general because common drivers, such as those on the Willcom W-Zero3 - do not support rendering in landscape mode (I wonder which devices DO support those features). After messing with this collectively for weeks we eventually went with the obsolete GAPI. The code here will probably not work for you.

For some reason, elementary DirectX operations are not very well documented in the .NET Compact Framework documentation; I kept running into InvalidCallExceptions for no aparent reason, and couldn't figure out the "simple" way to lock surfaces from the documentation (it's worth noting that I was only interested in basic 2D functionality).

Basically you just need the right set of flags and the right order of operations. Here's the code I used and that worked for me (even under the considerably buggy emulator). To create the device, use the following parameters:

PresentParameters p = new PresentParameters();
p.SwapEffect = SwapEffect.Discard;
p.Windowed = true;
p.EnableAutoDepthStencil = false;
p.PresentFlag |= PresentFlag.LockableBackBuffer;
p.MultiSample = MultiSampleType.None;
m_device = new Device( 0, DeviceType.Default, this, CreateFlags.None, p );

To draw on the backbuffer, you can use the following code:

m_device.BeginScene();

using ( Surface s = m_device.GetBackBuffer( 0, BackBufferType.Mono ) )
{
    int pitch;
    using ( GraphicsStream gs = s.LockRectangle( this.ClientRectangle, LockFlags.None, out pitch ) )
    {
        // Your code goes here...
    }   
    s.UnlockRectangle();
}

m_device.EndScene();
m_device.Present();

I hope this helps someone avoid a couple hours of frustration.

Tuesday, December 19, 2006 4:25:24 PM (Jerusalem Standard Time, UTC+02:00)  #    -
Development | Compact Framework
# Sunday, December 17, 2006

Word Shoot is reminiscent of Crimsonland's typing mode. Enemies advance at you and, in order to shoot them down, you have the type in the wordsthat show up below them. It's an excellent exercise for fast typing, not to mention a great way to get RSI.

Something's really screwed up with the high score system though; I scored 69,700 on my second game (hard difficulty, 9 missed words - at least 3 of which were because of overlapping enemies). I'm a fairly fast typist, and while I have no problem accepting the concept of people typing faster and/or more accurately than I do, still - 358,620 does not seem to me like an attainable score. I'll give it a couple more tries before I get back to work (we have a regularly scheduled flame throwing every Sunday. And no, I can't remember where that joke comes from).

Sunday, December 17, 2006 3:30:24 PM (Jerusalem Standard Time, UTC+02:00)  #    -
Gaming
# Thursday, December 14, 2006

I just reinstalled my laptop (a long and annoying story which I shall tell some other time), and this time opted for the Intel PROSet/Wireless drivers along with the PROSet/Wireless software suite (the one that replaces the crappy Windows wireless network management applet). It installed fine, the wireless card seemed to work fine but when I tried to start up the Intel application I was horrified.

It was in Hebrew.

Now, I realize that language preferences are a very personal issue, which is exactly why this pisses me off so much: why have ATi, nVidia and Intel all decided that my language of preference is Hebrew? The fact that my Windows is configured for Hebrew support in non-Unicode applications is no bloody excuse - it's that way because a lot legacy (and even new!) Hebrew applications require this setting to work properly. But my Windows is completely in English. Had I wanted localized UIs, I would've installed a localized version of Windows.

In Intel's defense, the translation was very comprehensive and even the RTL issues were sorted out; usually, however, software that supports localized menus have a language option where you can change the default language. The PROSet/Wireless software suite does not, and this time I was pissy enough to do something about it. Solution? Either download and import this registry hack, or do it manually:

  1. Start up your favourite registry editor;
  2. Go to HKLM\Software\Intel\Wireless;
  3. Change the value of InstalledLangId from whatever it is to 0x409 (or 1033 if you're decimal) -- that's the LangId for English;
  4. Change the value of InstalledLangShortString to "ENG";
  5. Kill the iFramewrk.exe process and restart it (or restart your machine if you're lazy)

All done. I really wish applications would stop deciding for me the language I want to work with.

Thursday, December 14, 2006 12:00:20 PM (Jerusalem Standard Time, UTC+02:00)  #    -
Software
Me!
Send mail to the author(s) Be afraid.
Archive
<January 2007>
SunMonTueWedThuFriSat
31123456
78910111213
14151617181920
21222324252627
28293031123
45678910
All Content © 2024, Tomer Gabel
Based on the Business theme for dasBlog created by Christoph De Baene (delarou)