Archive for category Software Development
Web development environment – “On The Go”
Posted by RyanG in Software Development, drupal, php on April 7, 2009
Over the past few weeks I’ve been spending most of my spare time developing a couple of web sites. These sites are based on the Drupal CMS written in PHP. And I’ve taken a bit of a crash course in Drupal module design.
When I set out developing these, I faced a challenge that I’d been aware of, but managed to avoid in the past. How do I work on these projects in a predictable, constant environment, and still bring my code with me to work on my home machine, work machine, laptop, and anything else I happen to sit down in front of?
This blog post is about how I’ve accomplished this so far. Read more after the break…
Read the rest of this entry »
Drupal Flickr Module. Now with URLs!
Okay, so I’ve been a bit preoccupied with a couple projects which have slowed my efforts at blogging etc.
In both cases, I’ve been working on websites that leverage the PHP based Drupal CMS. One of those projects is over at http://www.chasejarvisshoeproject.com. That site is basically a small community forum for some folks that are sending a pair of shoes around the world, and taking pictures of them in various locations and situations. Pretty cool. The result of this effort is a Flickr photo pool and a good time.
So, of course a website devoted to a group on Flickr, is going to require some integration with Flickr. Enter the Drupal Flickr Module. When I started using it, this module was still in either an alpha, or beta (can’t seem to remember) and has released it’s 1.0 as of the 25th of March. Throughout the time I’ve been using it however, there’ve been a few functions of the Flickr API which I needed, and the module didn’t support. Those were.
Since the framework of the module did the hard work of making the calls, it was easy to write my own methods which performed these Flickr API functions for me. And as the module developers released new versions, I just copy/pasted my code back into the new file, and went about my business.
Well when 1.0 was released, I took a closer look. It turns out they’d implemented the call to get photos from a group pool, but still nothing for the URL’s. So I figured I’d contribute and write a patch for the two calls I was still in need of. And that, is what you see here.
569,597d568
< }
<
< /**
< * @param $nsid
< * nsid of the group whose pool url will be returned
< * @return
< * The URL portion of the response from the flickr method flickr.urls.getGroup
< */
< function flickr_urls_get_group($nsid)
< {
< $response = flickr_request('flickr.urls.getGroup', array('group_id' => $nsid));
< if($response)
< return $response['group']['url'];
<
< return FALSE;
< }
<
< /**
< * @param $nsid
< * nsid of the user whose photostream url will be returned
< * @return unknown_type
< */
< function flickr_urls_get_user_photos($nsid)
< {
< $response = flickr_request('flickr.urls.getUserPhotos', array('user_id' => $nsid));
< if($response)
< return $response['user']['url'];
<
< return FALSE;
As you can see, pretty basic but I figured I'd contribute. I posted this as a feature request/issue over on the Flickr Module's issue queue, but have yet to receive a response. If nothing else, I can use this to patch the next version. Hopefully it helps someone else as well.
Really Detecting Design Mode
I recently had to deal with the problem of ADO.NET data access occurring on user controls, and forms in the Visual Studio design view. Now the data access depended upon a connection string in the App.config file and consequently, when run from Visual Studio it could not connect to the database since the connection string wasn’t available.
So, I proceeded to do some searching on the problem. I very quickly discovered the DesignMode flag for components, and thought I’d found my solution.
I promptly added the following to the UserControl that was blowing up when I opened it in the Designer.
public UserControlCtor()
{
InitializeComponent();
if(!DesignMode)
{
// Do the data access here.
}
}
I quickly discovered however, that the DesignMode flag wasn’t set until AFTER the constructor had run, and the parent object set the DesignMode flag on this control. Okay, simple enough we just move it to the OnLoad event for the UserControl right? Well, yes that would probably work in most cases however in our application this practice of doing data access in the constructors was rampant and therefore the dozen or so UserControls that were placed on this UserControl had the same problem. I’d need to make the this change to… well… pretty much every UserControl in the application. While that’s something that should happen, right now we cannot afford the technical debt to fix it.
Fortunately, all of our ADO.NET access in this application is abstracted into a library class which does all the data access, and handles things like opening and closing/disposing the database connection and just generally insulating users from the complexities of using ADO.NET. That’s the obvious candidate for the best place to filter design or runtime mode and either run the data access or not.
But wait, a helper class in the app won’t have a DesignMode flag and besides, how would it get set, you say? Well, in my travels looking for ways to detect that the code is running in design mode, I stumbled across several solutions. The most intriguing of which is the UsageMode flag. This can be checked in any class at any time and gives you an accurate gauge of what mode your code is running in.
So, in the few methods that do the data access in our ADO.NET abstracting class, I simply do the following.
if(System.ComponentModel.LicenseManager.UsageMode ==
System.ComponentModel.LicenseUsageMode.Designtime)
return;
This checks to see if we’re in design mode or not, and if we are simply bails out of the method effectively skipping the data access and solving our problem. Pretty cool eh?
I found several suggestions on how to detect design mode, they pretty much consisted of the following.
Microsoft’s Tlbimp creates leaky BSTR signatures
This one confounded me when I first discovered it, and I’ve recently been reminded about it. For the sake of remembering the details, and hopefully helping someone else out I’m going to document it here.
The problem is this. When you have a COM library that you need to use from a C# app, you import it as a reference. In the background the Microsoft.NET wizards do their magic by running the Tlbimp.exe to generate a managed DLL with all of the objects and interfaces from the COM library. You proceed to use the code that Microsoft so conveniently converted for you fully confident that all is well.
But it’s not. See, suppose your COM library has a method that returns a BSTR via an [out] parameter, or perhaps it defines an interface for a listener your managed code must implement. Suddenly there is the potential for a serious memory leak!
See, a BSTR in unmanaged code aren’t just any normal string. BSTR’s are allocated by the system by calling SysAllocString and subsequently released by calling SysFreeString. This poses a problem for managed code if you aren’t careful. Take the following listener interface for example.
*Interface names and GUID’s changed to protect the innocent
interface IImplementMeListener : IDispatch{
[
id(0x000000C9)
]
HRESULT _stdcall notify([in] TEventType eventType, [in] BSTR data );
};
The Tlbimp.exe generates a managed assembly with the following signature for this same method.
[ComImport, TypeLibType((short) 0x10c0), Guid("00000000-0000-0000-0000-000000000000")]
public interface IImplementMeListener
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(0xc9)]
void notify([In, ComAliasName("ExampleLib.TEventType")] TEventType eventType,
[In, MarshalAs(UnmanagedType.BStr)] string data);
}
Which means when you implement this interface in your managed class, you’ll just have String as the data type for the second parameter. Which might look like this.
class MyManagedListener : ExampleLib.IImplementMeListener{
public void notify(ExampleLib.TEventType eventType, String data)
{
DoSomethingWithData(data);
}
}
So this is what happens.
1) Your COM library allocates the string to pass into your listener using SysAllocString.
2) Your COM library passes the newly allocated string into your managed app by calling the notify method of your listener.
3) Your managed app does whatever it’s going to do with the string, then returns.
Normally in a fully managed app this would be no problem, when the reference count to the string finally reaches 0, the garbage collector sweeps it up and the memory is reclaimed. However, in this case we have a problem. The COM library allocated the string, and passed it into your managed app, and it’s responsibility for that string ends there. The expectation is that the client will release the BSTR by calling SysFreeString. Clearly we can’t explicitly do that to the managed String type.
So what do we do? We rewrite the part of the assembly that Tlbimp.exe made for us, and adjust our listener implementation slightly.
This is how I did it, though there may be better ways.
1) Use a disassembler to view the code of the Tlbimp.exe generated assembly for your COM library. I used, Lutz’s Reflector.
2) Copy the code for the entire library into a *.cs file, then change just the signature of the method you’re concerned with.
The new signature should look like this.
[ComImport, Guid("00000000-0000-0000-0000-000000000000"), TypeLibType((short) 0x10c0)]
public interface IImplementMeListener
{
[MethodImpl(MethodImplOptions.InternalCall, MethodCodeType=MethodCodeType.Runtime), DispId(0xc9)]
void notify([In, ComAliasName("ExampleLib.TEventType")] TEventType eventType,
[In] IntPtr data);
}
And your implementing class changes to this.
class MyManagedListener : ExampleLib.IImplementMeListener{
public void notify(ExampleLib.TEventType eventType, IntPtr data)
{
String dataStr = Marshal.PtrToStringBSTR(data);
DoSomethingWithData(dataStr);
Marshal.FreeBSTR(data);
}
}
This is not particularly tricky wizardry. All we’re doing is marshaling the input value from the library as an IntPtr instead of a managed String. This allows us to explicitly release it using the System.Runtime.InteropServices.Marshal.FreeBSTR method, just like the library expects us to do.
Hopefully, this will save you some hastle, and avoid a potentially large memory leak.