Adding methods, properties, and events
As mentioned, this does not provide a tutorial on C# or on C# Express; the objective is to provide a template for building C# COM DLLs. The functionality of the DLL is manually coded in the Demo.cs file. Its content is as follows:
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.InteropServices;
namespace QuoteQuad
{
public delegate void EventDel();
[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIDispatch)]
public interface UserEvents
{
[DispId(5)]
void MyEvent();
}
[InterfaceType(ComInterfaceType.InterfaceIsIDispatch)]
public interface _Demo
{
[DispId(1)]
int MyMethod(int numarg);
[DispId(2)]
string MMethod();
[DispId(3)]
int MyProperty { get; set;}
[DispId(4)]
void eventm();
}
[ClassInterface(ClassInterfaceType.None)]
[ProgId("QuoteQuad.Demo")]
[ComSourceInterfaces(typeof(UserEvents))]
public class Demo : _Demo
{
public event EventDel MyEvent;
public Demo()
{
}
private int myVar;
public int MyProperty
{
get { return myVar; }
set
{
MyEvent();
myVar = value;
}
}
public int MyMethod(int numarg)
{
return numarg + 10;
}
public string MMethod()
{
return "Ajay Askoolum";
}
public void eventm()
{
MyEvent();
}
}
}
The critical parts of the code are:
• The DispId attributes must be unique integers.
• Events are declared in the public interface UserEvents block and methods and properties are declared in the public interface _Demo block.
At this point, a C# language manual is necessary in order to be able to build reasonable functionality in the DLL.
Building the DLL
In order to make the assembly, click Build|Build Solution or press F6. This process creates several files, including the DLL at the following location
C:\OurFiles\Ajay\C#\QQ\QuoteQuad\QuoteQuad\obj\Release
The location will vary depending on the specification for Location; see Figure 7.
The only file that is required for COM operation is:
C:\OurFiles\Ajay\C#\QQ\QuoteQuad\QuoteQuad\obj\Release\QuoteQuad.dll
On the development computer, no further action is necessary before using the DLL as the build process has already registered the DLL silently, and can be seen from APL+Win:
'#' ⎕wi 'XInfo' 'QUOTE'
QuoteQuad.Demo ActiveObject QuoteQuad.Demo
Deploying the DLL
Figure 8. QUOTEQUAD.DLL properties
The DLL’s properties can be examined by collating it within the filing system and clicking the right mouse button: see Figure 8.
On the target computer, execute the following steps:
1. Ensure that there are no existing sessions of a client that will use the DLL.
2. Ensure that it has the .Net Framework 2.0 installed already.
3. Copy the DLL to a target computer at any suitable location.
In principle, it is inadvisable to copy the DLL to a system folder such as System32; a good location is the folder housing the application that will deploy the DLL. For the purpose to hand, the DLL is copied to C:\MY APL APPLICATION.
In order to make the DLL available, click Start|Run to display the dialogue shown in Figure 9.
In the Open box, type:
C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\RegAsm.exe …
… /codebase "C:\MY APL APPLICATION\QuoteQuad.dll"
Figure 9. Registering the DLL
Click OK.
The code in the box shows the fully qualified name of REGASM.EXE followed by the switch /codebase and then the fully qualified name of the DLL. The file locations vary on your computer.
Testing the DLL
At this point, the DLL is available on the target computer and is readily deployed by APL.
Using APL+Win, an instance of the DLL is created as shown in Figure 10.
Figure 10. APL+Win
Using APLX, an instance of the DLL is created as shown in Figure 11.
Figure 11. APLX
Using Dyalog, an instance of the DLL is created as shown in Figure 12.
Figure 12. Dyalog
APL+Win and APLX are consistent in the enumeration of the events, methods, and properties of the DLL. However, it is unclear why Dyalog is unable to see the event.
Demonstration
I shall use APL+Win to demonstrate the usage of the DLL. First the properties:
⎕wi '?MyProperty'
xMyProperty property:
Value@Long ← ⎕WI 'xMyProperty'
⎕WI 'xMyProperty' Value@Long
The property MyProperty is a read/write property that is numeric.
⎕wi 'xMyProperty' ⍝ Read
0
⎕wi 'xMyProperty' 100.75 ⍝ Write
⎕wi 'xMyProperty' ⍝ Read
101
There appears to be an inconsistency! On closer examination of the code, it is apparent that the DLL coerces the value of the property to integer; hence, the result is 101 instead of 100.75.
public int MyProperty
{
get { return myVar; }
set
{
MyEvent();
myVar = value;
}
}
This property will also raise the event MyEvent upon the value of the property being changed. However, the event was raised in the previous assignment but I had not specified an event handler. An event handler is specified in the usual manner, thus:
⎕wi 'onXMyEvent' '0.01×+\10/1' ⍝ Specify event handler
⎕wi 'xMyProperty' 190254 ⍝ Expect handler to run
0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 0.1
⎕wi 'xMyProperty' ⍝ Verify
190254
The event handler did fire and ran the APL handler; any APL+Win function may be called by the handler.
The method eventm also raises the event MyEvent.
⎕wi 'Xeventm' ⍝ Call method & expect MyEvent to fire
0.01 0.02 0.03 0.04 0.05 0.06 0.07 0.08 0.09 0.1
The method MMethod simply returns a static result:
⎕wi 'XMMethod' ⍝ This method returns a string
Ajay Askoolum
Finally, the method MyMethod takes a single argument and returns it incremented by 10.
⎕wi '?MyMethod'
XMyMethod method:
Result@Long ← ⎕WI 'XMyMethod' numarg@Long
⎕wi 'XMyMethod' 190254
190264
Although the methods, properties, and events in this demonstration C# COM DLL are simple, it is clear that it is now possible to write COM servers in the Microsoft flagship language, C#, for deployment with APL. Moreover, the template developed in this article for building and deploying such DLLs is minimalist, as would become clear from a study of the subject. For instance, I have completely circumvented the issues relating to strong names, the Global Assembly Cache and the debate related to managed code.
Share with your friends: |