Notes from Daily Encounters with Technology RSS 2.0
 
# Sunday, May 14, 2006

Less than a month ago I was certain I’d never have to write managed code in C++. With such a set of mind I didn’t really care about the new features being added and improvements being made to managed C++ since the first Visual Studio .NET. Luckily there were people thinking otherwise and as a result this – often overlooked – member of the .NET family got better with every release and is actually quite nice in the 2005 version. Don’t get me wrong – it still is C++ and you probably wouldn’t want to use it if you could get away with C# or VB. But if platform invoke is giving you too many headaches you might want to take a look at it. It could be the easiest way to solve your problem.

To make this a little bit easier for those of you who haven’t used C++ for some time and didn’t bother to check managed C++ at all, I’ll provide a small sample to help out with the beginner’s problems I had when starting out.

In a situation like mine you’ll usually want to write a class library to wrap the unmanaged calls for undisturbed use within you managed project. In my case I’ll be implementing an interface but writing a standalone class is not much different.

Let’s start with the header file. You might remember that C++ requires the separation of class declaration from method definition, the former being done in a header (*.h) file and the latter in a code (*.cpp) file. I admit being a little bit spoiled by not having to do that any more in C#. Let’s name our header MCPP.h (fell free to guess what it stands for):

using namespace System;

namespace DamirsCorner
{
   namespace Samples
   {
      namespace LateBinding
      {
         public ref class MCPP : IBind
         {
         public:
            virtual String^ Together(String^ first, String^ second);
         };
      }
   }
}

It looks like a hybrid between C++ and C# and one could argue that’s what it actually is. I’d like to point out the following:

  • The using directive has an additional keyword namespace. Also a double colon (static separator in C++) would be used to separate nested namespaces instead of a dot. You’ll see this in the code file which follows.
  • To put your own code into a nested namespace, you’ll have to actually nest the namespace declarations. Separating several of them with double colons won’t work.
  • To declare a managed class, use the additional keyword ref.
  • Don’t forget the different use of the public keyword for the members in C++ compared to C#.
  • The ^ character denotes a reference to a managed object (stored on the managed heap), separating it from unmanaged pointers (* character).
  • Notice the interface IBind being implemented by the class. A standalone class wouldn’t need this of course. The virtual keyword in the method declaration would also be skipped in this case.

This is it for the header file. Let’s look at the code file now:

#include "MCPP.h"

using namespace System;
using namespace DamirsCorner::Samples::LateBinding;

String^ MCPP::Together(String^ first, String^ second)
{
   return String::Empty;
}

It’s pretty obvious the method doesn’t really do anything but it’s the skeleton we’re focusing on at the moment. You should turn your attention to the following:

  • The code file must include the header file it implements (i.e. defines its methods). To refresh your C++ knowledge: it’s a good habit to use quotes for internal project header files and pointy brackets for external library header files. The compiler looks in the project directory first for the former and in the include directories first for the latter. It checks the other location if it doesn’t find the file but it will work faster if you use the right one (not to mention that by doing it you’re avoiding the problem of locating the wrong include with the same name).
  • You can notice the double colons as namespace separators as I mentioned before.
  • The methods you’re implementing are not within the class declaration any more. You already declared the class in the header file therefore you only set the method class membership here by prefixing its name with the class name and a colon, just like you were calling a static method.
There’s a reason I used String for parameter and return value type. While value types can be directly used in unmanaged code, reference types have to be correctly marshaled. But that’s a complex enough topic to justify a separate posting. The only thing left for this one is to make the code above compile. Just start a new Class Library project in C++ (you’ll find it in the CLR group) and paste the code to the right files. After you reference the assembly containing the interface used (similar to doing it in C#) the code should build successfully.
Sunday, May 14, 2006 7:11:27 PM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | .NET | C++ | Interop

Trying to build a C++ project opened from a network share in Visual Studio 2005 might fail with a strange error: Command line error D8022 : cannot open '$(OutDir)\RSP00000115642624.rsp'. Double clicking it in the Error List window crashes the Visual Studio. The issue is reported in the MSDN Product Feedback Center.

Additional exploration and experimentation revealed that the problem only appears when the share host can’t authenticate the user reading from and writing to the share. This means there will be no error when the user and the share hosting computer are in the same domain. You can find a more thorough explanation in the following MSDN forum post.

Unfortunately this usually isn’t the case in the home environment. It’s best you just avoid the problem altogether by opening the project from a local drive. Just use a version control system or a synchronization tool to assure the same files are on the local machine and on the server when you need to.

Sunday, May 14, 2006 4:05:50 PM (Central European Daylight Time, UTC+02:00)  #    Comments [0] - Trackback
Development | C++ | Software | VisualStudio
# Wednesday, May 03, 2006

Completely unexpectedly I stumbled across Platform Invocation Services today when I was introduced to the IBM Tivoli Storage Manager API. It should have been a simple case of getting to know the API and writing a sample application with it, but it turned out that there’s no managed wrapper available for it (in spite of first being told otherwise). Combine that fact with an abundance of low level calls and large structs as their parameters and you can imagine that after one day there’s still a long way to that sample application, not to mention the final solution.

For anybody else like me out there who hasn’t done more than an occasional DllImport call or two the following resources should help getting to grips with the PInvoke basics:

  • Platform Invoke Tutorial – a must read for anyone starting with PInvoke. As usual, the follow-up links provide lots of additional useful information.
  • PINVOKE.NET – an indispensable source of information on WinAPI PInvoke calls. Not exactly what I needed but still the abundance of example calls turned out helpful.
  • The P/Invoke Wizard – a simple tool for converting C/C++ include files to PInvoke declarations. Not perfect and a bit pricy for what it does but still worth it due to the time it can save you when dealing with many large include files.
I hope you find these useful just as I did.
Wednesday, May 03, 2006 11:34:25 PM (Central European Daylight Time, UTC+02:00)  #    Comments [1] - Trackback
Development | .NET | Interop
# Tuesday, April 18, 2006

Today I’ve been evaluating database designs made by this year’s candidates for work at our company. One of the issues I’ve been encountering all the time was the handling of date and time values. The SQL Server’s common data type datetime for both values has been the source of quite some confusion, especially since the values required to be separate at some occasions and joined at others.

I suppose the decision on whether to store them separate or joined depends on how the values are going to be used. In most cases the extra storage space required by using separate columns for both values isn’t worth it but in some usage scenarios the resulting reduced query complexity and improved indexing usage can justify it.

Either way sooner or later the need for separating or joining the date and time parts will arise. The following query demonstrates both operations in what I believe is the most efficient way:

SELECT
   dateOnly = CONVERT(datetime, FLOOR(CONVERT(float, dateTimeColumn))),
   timeOnly = dateTimeColumn - CONVERT(datetime, FLOOR(CONVERT(float, dateTimeColumn))),
   dateAndTime = dateOnlyColumn + timeOnlyColumn 
FROM DateTable

Tuesday, April 18, 2006 11:38:07 PM (Central European Daylight Time, UTC+02:00)  #    Comments [1] - Trackback
Development | SQL
# Wednesday, March 22, 2006

The following query is a good starting point if you want to export the SQL Server Agent job history to a file and you’re still using Enterprise Manager from SQL Server 2000. In SQL Server Management Studio from SQL Server 2005 there’s already a command available to do this in the Log File Viewer window accessible from the View History command on the selected job.

USE msdb
SELECT
   J.name, 
   S.step_id,
   S.step_name, 
   H.message, 
   run_status = CASE H.run_status
      WHEN 0 THEN 'Failed'
      WHEN 1 THEN 'Succeeded'
      WHEN 2 THEN 'Retry'
      WHEN 3 THEN 'Canceled'
      WHEN 4 THEN 'In progress'
   END, 
   H.run_date, 
   H.run_time, 
   H.run_duration
FROM sysjobhistory H
   INNER JOIN sysjobsteps S ON H.step_id = S.step_id AND H.job_id = S.job_id
   INNER JOIN sysjobs J ON J.job_id = H.job_id
ORDER BY H.job_id, H.run_date, H.run_time, S.step_id

Wednesday, March 22, 2006 11:42:26 PM (Central European Standard Time, UTC+01:00)  #    Comments [0] - Trackback
Development | SQL
Sponsored Ads

About Me

Damir Arh

Microsoft Certified Professional

View Damir Arh's profile on LinkedIn

Profile for ExAmigan

ExAmigan

Twitter
Damir's Corner: Avoiding Queue Starvation in CruiseControl.NET http://goo.gl/fb/G52YB 1 day ago
RT @aleksj: From http://last.fm/robots.txt: Disallow: /harming/humans, Disallow: /ignoring/human/orders, Disallow: /harm/to/self #asimov 2 days ago
Eagle Eye on DVD was a pleasant surprise. It passed under my radar when it was first released. 5 days ago
Multiple RTM gadgets in iGoogle suddenly can't show different lists anymore http://digs.by/aD5AbJ 6 days ago
Notifications for new projects in CCTray are a nice new feature of #ccnet 1.5 7 days ago
The opinions expressed herein are my own personal opinions and do not represent my employer's view in any way.

All Content © 2010, Damir Arh, M. Sc. Send mail to the author(s) - Privacy Policy - Sign In
Based on DasBlog theme 'Business' created by Christoph De Baene (delarou)