Using .NET components in Team Developer 3.1

One of the great advantages of TD is that you can extend the functionality of Sal by external components. Thus you can take advantage of the high productivity of the 4GL – low learning curve, very fast programming – with the advantages of the vast capabilities of the .NET framework. Unfortunately.NET can be used only  with version 6.0 of TD easily. For versions below, there is the possibility, however using .NET functionality via COM objects. As an example, I want to call the MD5 hash function from the .NET framework so that you can calculate an MD5 hash value for TD strings and blobs. Remark: It is also easily possible to use the more modern hash functions RIPEMD160, SHA1, SHA256, SHA384, and SHA512 instead. See the MSDN library.

Creating the COM object in C#

Here the recipe to build a COM Object which wraps the .NET function MD5.ComputeHash(..):
  1. In Visual Studio (for example the free visual C# 2010 Express) create a new project of type ClassLibrary named DotNet2Com.
  2. The Assembly must be registered for COM. To do so call the context menu of DotNet2Com in the Project Solution Explorer, select Properties. On the tab Build check Register for COM interop.
  3. In Project Solution Explorer doubleclick ‚AssemblyInfo.cs‘, look for the entry [assembly: ComVisible(true)] and set it to true if necessary.
  4. Rightclick the file called Class1.cs and rename it via context menu to Md5.cs (including the references).
  5. In the file Md5.cs add the using directive
    using System.Runtime.InteropServices;
  6. Define an interface in Md5.cs – outside the class MD5 but within the namespace:
    public interface IMd5
    String ComputeHash (Object buffer);
    The interface is necessary so that Visual Studio builds a DLL which provides this function with a COM interface so that it is also visible to the TD. Since the TD can only import latebound functions, the attribute InterfaceIsDispatch must be used. InterfaceIsDual is also possible (which indicates to VS to implement both interface types), but not InterfaceIUnknown.
    For the input buffer I chose type Object rather than byte []. The reason for this is that ActiveX Explorer of Team Developmer wraps type byte [] to a SafeArray. Type Object is interpreted by the TD, however, as a Variant. Both would work but the Variant is substantially easier and faster for passing strings (which may include text as well as a BLOB in TD).
  7. Now class MD5 must be modified so that it implements our interface:
    public class MD5: IMd5
Let’s start now with the actual programming:
To use the MD5 functions, they must be incorporated by
using System.Security.Cryptography;
The actual function looks like this:


public String ComputeHashAsHex(Object buffer)
// parameter checking
if (buffer == null)
return String.Empty;

// Cast buffer from type Object to a byte[] array
byte[] bIn = (byte[])buffer;
// Check length

if (bIn.Length == 0)
return String.Empty;

// Instantiating of MD5 is a little bit uncommon (would expect MD5 md5Hash = new MD5() )
// but MSDN-Library tells us this

MD5 md5Hash = MD5.Create();

byte[] output = md5Hash.ComputeHash(bIn);

// Cast the 16 bytes to a HEX-String with 32 chars
StringBuilder sb = new StringBuilder(32);
foreach (byte bt in output)
// casts a byte in a 2-digit hex
return sb.ToString();

That’s it, the COM object can be built.

Incorporating the COM object in the Team Developer

An .apl wrapper must be created to use a COM object. In TD start the ActiveX Explorer (Tools menu) and select the library „DotNet2Com“. The ActiveX Explorer inspects the COM object and displays its contents. It is ok to just select the interface IMd5 and then „generate full by name“ to create the DotNet2Com.apl.
The file is found in \Gupta\AxLibs. It is now also automatically – together with the Automation.apl – part of the current TD project as a library. For example, the COM object can be used like this:

Function: HelloWorldMd5
Static Variables
Local variables
FunctionalVar: cMd5
Class: DotNet2Com_IMd5
FunctionalVar: vBuffer
Class: Variant
String: sMd5
String: sIn
! Instantiate COM-Objekt – Default-name is: Namespace.Classname
Call cMd5.CreateObject( ‚DotNet2Com.Md5‘ )
! Set the input
Set sIn = ‚Hello World‘
! Since a String like the one above includes a terminating zero we can cut this out with
 Call SalStrSetBufferLength(sIn, SalStrLength(sIn) )
! Store String as Blob in Variant
 Call vBuffer.SetBlob( sIn )
Call cMd5.ComputeHashAsHex( vBuffer, sMd5 )
Call SalMessageBox( ‚The Md5 Hash for
„Hello World“
‚ || sMd5, ‚Success‘, MB_Ok)

The result:
That’s it for now.
Finally the downloads for the above code:

Visual Studio Project
TD Project

I’d appreciate your feedback.
Happy coding!

Über thomasuttendorfer
Ich bin Entwicklungsleiter bei der Softwarefirma [ frevel & fey ] in München. Wir entwickeln Business-Software für Verlage und verwenden dafür den Gupta Team-Developer sowie Visual Studio.

Kommentar verfassen

Trage deine Daten unten ein oder klicke ein Icon um dich einzuloggen:

Du kommentierst mit Deinem Abmelden / Ändern )


Du kommentierst mit Deinem Twitter-Konto. Abmelden / Ändern )


Du kommentierst mit Deinem Facebook-Konto. Abmelden / Ändern )

Google+ Foto

Du kommentierst mit Deinem Google+-Konto. Abmelden / Ändern )

Verbinde mit %s

%d Bloggern gefällt das: