|Delphi Clinic||C++Builder Gate||Training & Consultancy||Delphi Notes Weblog||Dr.Bob's Webshop|
More and more software products are a conglomerate of subsystems produced with a multitude of tools. One of the problems there is to be able to store messages of all those subsystems in a uniform way. Enter Raize Software Solutions with CodeSite. It integrates very well with Delphi and C++Builder, however, we also would like to use it from other kinds of tools.
Remember the times in ancient history that required of you that you had to do debugging with printf statements? Or examining large unwieldy logfiles full of terse debugging text? Raize Software Solutions makes a program called CodeSite. What it can do is display messages of all kinds and even the content of dumps etcetera. It is very well integrated with Delphi and C++Builder. You can purchase licences from Raize Software Solutions Inc. Beside this product, they have components for Delphi and C++Builder. Bob Swart thinks very favorable of this component suite, and I can tell you that the second version is in the making.
The problem I am trying to solve here is that you want to have a means of keeping track of multiple applications that work together. In some cases it can be very beneficial if you can track the things a program is doing relatively to what another program is doing. Doing this might enable you to solve race conditions or other interactions between multiple processes. However, we have to make sure that in the message handling we do not have race conditions, and CORBA can give us that.
What I would like to show is that middleware is a very good way of making integrated message handling a possibility. I tried to do this for Delphi, C++Builder, Borland C++ 5.02, Borland JBuilder 2, Microsoft Visual C++ 5 and last but not least Aion. That last name is the name of a development environment we're using heavily to produce knowledge based systems. I'll restrict myself to Borland Delphi and C++ Builder.
The architecture I have in mind is as follows. CodeSite is controlled by a CORBA server process. Next, I want to make clients in all tools mentioned. The server 'publishes' a number of methods that CodeSite can service, and the CORBA clients make use of those services.
Actually, I made the server in Delphi4. That is quite easy. However, one detail to remember is that if you have a program group that contains the server program as well as the client program, you have to make sure that you activate the server program in the Project Manager before opening the Type Library Editor. If you do not, it appears as if you lost your stuff, which is not the case. What you do is to add a new CORBAObject to your project. Name it, set the options to the values you want and go to the code editor. If you want to add to the interface of the CORBA object, rightclick in the code editor and select 'Add to Interface'. Not exactly the first place you would look. What you see in the Type Library Editor if you add to the interface is that it adds the stuff you enter.
The C++Builder client
Building the C++ Builder client was a bit involved. First, I had to devise a way in which I could generate the client side for C++ Builder. One way of doing that can be to use the xxx_tlb.pas stuff generated by Delphi, but that was not what I wanted to do. What I wanted to show was that we can use C++ Builder to generate a client just using the possibilities of the VisiBroker tools. What I did was to export the type library from Delphi into a CORBA IDL specification. That in turn I used to generate the C++ client code with the idl2cpp generator that comes with VisiBroker. What that shows is that you can produce a client for any CORBA server for which you have the interface specification in IDL form. Making a client program, compiling and linking was easy enough, however, the program crashed the moment I wanted it to run at several different and odd places. I had to resort to a number of relatively oldfashioned debugging techniques. First of all, I looked at the message window to see what DLLs were loaded and in what order. What I saw was that my program loaded cw3240.dll as well as cp3240.dll. Since both were residing in the C++ Builder bin-directory, I looked at the properties of the two DLLs. They both claimed to be runtime DLLs of C++ Builder. Hmmm. Now that could be the problem. Trying to initialize a runtime library DLL twice is a good reason for having trouble. The next question was why the program attempted to load them both. The answer is that if you use VisiBroker as client and a s a server, you load a DLL called orb.dll. Inspecting this DLL with QuickView told me that that DLL loaded cw3240.dll as its runtime library. The client program itself loaded cp3240.dll as its runtime library.
The last question naturally was how to get around this situation.
Some searching lead me in the direction of the linker tab in the project options dialog.
Turning of the checkbox 'Use dynamic RTL' did the trick! What happens if it is turned off is that runtime stuff is linked into the application instead of linked in dynamically with an import library.
End of problem number one.
The next problem was that the program kept aborting with an error message telling me my client 'raised exception class IODictionary
What I showed here is that it is possible to make clients just by using the VisiBroker tools. Ok, I cheated a little by generating the necessary IDL source from Delphi, but that is just a shortcut. If you have an interface specification in the form of CORBA IDL, you can make client programs that work.