Now that we've shipped, I can finally start talking about new features. So I'll start off with my personal favorite: soft declares.
When you make a normal declare, the declaration is stored off in the import table of the executable. When the system goes to load the executable into memory, it tries to resolve these declarations. If one cannot be found, then the load is terminated and the application cannot run.
A soft declare is different in that the declarations aren't stored in the import table. They're resolved when the application is running. If a function cannot be loaded (or its library), then a FunctionNotFoundException is thrown when you try to call the function.
So why is this cool?
For a few reasons. My primary love for this feature stems from the fact that you can support unicode functions on Windows. But there are other cool benefits as well, such as better support for LibC declares on Linux. You see, LibC is really a linker script for gcc! We now parse that linker script and resolve where the actual LibC library lives. In 5.5, you'd have to declare against the actual version of LibC you wanted. But in RB2005, you can soft declare against any version of LibC that's installed. Neato!
So how do you use one of these bad boys properly? I'll show you a quick and simple example of how to get the username for who's logged in (on Windows).
[rbcode]
#if TargetWin32
Soft Declare Sub GetUserNameA Lib "AdvApi32" ( name as Ptr, ByRef size as Integer )
Soft Declare Sub GetUserNameW Lib "AdvApi32" ( name as Ptr, ByRef size as Integer )
dim mb as new MemoryBlock( 256 )
dim size as Integer = mb.Size()
if System.IsFunctionAvailable( "GetUserNameW", "AdvApi32" ) then
GetUserNameW( mb, size )
return mb.WString( 0 )
else
GetUserNameA( mb, size )
return mb.CString( 0 )
end if
#endif
[/rbcode]
The way this works is simple:
We make our soft declaration for both the W (Unicode) and A (ANSI) versions of the API. Then we use the IsFunctionAvailable method call to see whether we can call the Unicode version. Making this call will try to locate the library and the function pointer from the strings passed in. If it can find both, it loads them into memory and caches them (for speed reasons). Then we make the proper call. The proper call checks to see if we have loaded the function pointer yet. If we have, it calls it. If we haven't, then it tries to load the library and function pointer. If it can't load it, then it raises a FunctionNotFoundException. If it can find it, then it caches it and calls it.
So there is a minor speed it from using soft declares. The first time the declare is loaded is where the majority of the speed hit is incurred. However, each time you call the function, it still needs to see if the function pointer is non-nil. But to be honest, the speed decrease is negligible.
The entire Windows Functionality Suite 2.0 has been converted to use the new Soft Declare functionality. This is the only reason I was able to make the suite Unicode savvy. Without the weak linking aspect of this feature, you could use the W version only on Windows NT 4 and higher. If you tried to use the W version on Windows 98, it would refuse to load (unless the user had the proper Unicode libraries installed, which most people don't have). But now, you can use the Suite on any version of Windows and it'll do the right thing.
Leave a comment