Freigeben über


Adventures in writing managed VSIP packages

It has been a little too long since I last made a post. A lot has been going on since the last time I wrote, mostly I have been working on getting bugs fixed for the “Whidbey” build of VS, and work has been proceeding on a new wizards tool for VS (while my last post said I would have some information about this wizard, we decided to wait for any announcements about it). Another task that has consumed my time is my IL editor/project sample. As you may know, I have been working on an IL editor and project system sample. If we get a Whidbey version of our book, then any chapters about VSIP will discuss these samples, and I am looking into getting them into a future version of the VSIP SDK. All major work on these samples were completed over the weekend, and only some minor bugs remain. As I mentioned before, the samples that I have been working on were written using ATL, but after some careful thought I decided that they should be converted to C#. So last night I got the latest build of the Everett Extras (interop assemblies for programming the Everett VSIP model – for now I am doing my development against the Everett version of VS) and sat down to convert my existing code from C++ to C#.

 

Converting the text editor took me a total of about 4 hours. 4 hours! I was expecting it to be much more complicated than it turned out to be, and most of those 4 hours were spent trying to track down an exception that was being thrown within my colorizer because of a bounds checking bug in my C++ code. I did not have any prior experience using the VSIP Extras SDK before last night, so I cannot say that it was easy because I knew how to use the Extras IAs, it was easy because there were only minor differences between the C++ and C# code.

 

The process was not flawless, however. I was bitten a few times because of some of the odd data types that the IAs seems to use and the conversion of those types to managed types. For example, there are a number of System.IntPtr objects that are passed back and forth, usually when a WCHAR* type is used on the unmanaged side. In this case you want to call System.Runtime.InteropServices.Marshal.PtrToStringUni to convert to a managed string (not PtrToStringBSTR like I was using at first, which would cause an immediate crash). I also had some problems setting up a service provider, I had to try overriding a number of different methods to get it working correctly – and there may be code in the Extras helpers to handle doing that in a cleaner way (don’t forget the Marshal.QueryInterface method, this will help you a lot when trying to implement your service provider). There also has been a noticeable slowdown when switching to a managed language, but most of that is, I believe, a problem with my code and not so much related to managed code. I am doing a lot of string manipulations in the colorizer, and a quick look over the code reveals many places where I can use StringBuilders rather than strings to speed up my code. I was also using a lot of pointers to keep track of positions into strings for optimizations, and when I converted to C# I had to undo those changes.

 

The next few days will be spent doing some optimizations on the code, and then I will start working on converting the project code to C#. When this experiment is done the packages will be written in both C# and VC for side by side comparisons, and maybe I will try converting to the other languages also. I don’t know of any packages written using VB and J#, and maybe as a proof of concept of using the IL editor/project I can convert them to IL.

 

 

Just as I was getting ready to post this, mail was circulated describing how to proffer a service from managed code using code such as this

 

            container.AddService(service.GetType(), service, false);

 

inside the Initialize method of a package. I noticed that method last night and tried to use it, but I could not get it to work correctly. I will try it again with my code and see where I went wrong.

Comments

  • Anonymous
    March 09, 2004
    Actually I think you might want to set the last bool (promote) to true, to propagate the service all the way up to VS land, otherwise it's going to stay limited to the service container that you're adding it to.
  • Anonymous
    March 10, 2004
    You are probably right, but the code I put in this post was not actual code that I will use, I just saw it in some mail that was sent around and I copied & pasted into this post. So while that bool should be true, I cannot say at this point without trying the code.