Stephen Smith's Blog

Musings on Machine Learning…

Posts Tagged ‘roto

The Sage 300 System Manager Core DLLs

with 9 comments

Introduction

We hold a developer’s exchange (DevEx) every couple of weeks where one of our developers volunteers to present to all the other developers in our office. This past week I presented at the DevEx on what all the core DLLs in our Sage 300 runtime folder do. I thought this might be of interest for a wider audience so here are the gory details.

Architecture

Our marketing supplied architecture diagram is the following which highlights our three tiers and hide a lot of the details of how the object repository, APIs and supporting services are implemented. I’ve blogged previously on our Business Logic Views. In this article I’m going to go into more detail on all the DLLs that provide the framework to support all of this.

arch

Lower Level DLLs

If you are an ISV developing Sage 300 SDK applications or have worked for Sage on the 300 product then you will have had to encounter a number of these DLLs. I’m only looking at a subset of current DLLs, and I’m not looking at all the DLLs that support older technologies that are still present to maintain compatibility with add-ons.

lowleveldlls

I didn’t add arrows to this diagram since everything pretty well calls everything else below it. But segregated the DLLs a bit by how low or high level they are. So here is a quick synopsis of each one:

A4wcompat.dll: We created this DLL back when we did a native port of the Sage 300 Views for Linux. This DLL isolates operating system differences that need more than some clever #defines. A big part of this is the thread and process synchronization and locking support. Even though we never released the native Linux version, this isolation of operating system dependent parts had made adding multi-threading support, 64 bit support and Unicode support easier.

A4wmem32.dll: In 16 bit Windows, the built in memory management was really slow, so everyone used their own. Now this DLL uses the Windows and C default memory management, but is still important for global memory that needs to be shared across processes. Originally this was done through the data segment of a fixed DLL, but now is done through memory mapped files.

A4wlleng.dll: This is just a language DLL that holds some lower level error messages used by System manager.

A4wsqls.dll: This is the SQL Server database driver (there is also a4worcl.dll for Oracle and a4wbtrv.dll for Pervasive.SQL). This is dynamically loaded based on the type of database you are connecting to. For more on our database support see this article.

Cato3msk.dll, cato3dat.dll: The cato3 DLLs are the old CA common controls. We don’t use these in our UIs anymore, but cato3msk.dll provides our mask processing that is used by the Views. Similarly we don’t use this date control, but do use a routine here to format dates in error messages correctly.

A4wroto.dll: This handles the loading of the various View DLLs as well as the various UIs we’ve used in the past. It loads the roto.dat files and handles loading the right DLLs when View subclassing is going on or stub Views need to be used.

A4wsem.dll: This handles the locking of the semaphor.bin file. It allows processes to lock the company database, an application or the whole site. It also handles application specific cross workstation locking needs.

A4wrv.dll: This is the main DLL API entry point for the Views. It manages all the calling of the Views and handles other tasks like sending the calls for macro recording. For more on our View interfaces see this article.

A4wapi.dll: This is quite a hodge-podge of services for the Views like revision lists, error reporting and such. It also has support routines for the older CA-Realizer UIs. This is quite a big DLL and has most of our C level API in it.

A4wrpt.dll: This is our interface to Crystal Reports, it started as our interface to CA-RET then was converted to Crystal using their CRPE DLL interface, then converted to Crystal’s COM interface and now uses Crystal’s .Net Interface.

A4wprgt.dll: This DLL handles replicating the system database tables into the various company databases when needed.

A4wmtr.dll: This is our meter DLL for long running processes. It can either put up a meter dialog or just report back to the caller, the current status and percent complete. It also provides the API for cancelling long running processes.

Higher Level APIs

The next level are some of the DLLs that make up our Java, COM and .Net interfaces. There is a bit of complexity here due to how our previous web deployed system worked. Here we could communicate back to the server originally using DCOM and then later with .Net Remoting. The .Net Remoting layer provides both the communications layer for this web deployed mode and also acts as our .Net API. Depending on how you create your original session will configure which actual DLLs are used and which are calling conventions are used.

higherlevelapis

A4wapiShim.dll: This is the C side of our Java JNI layer. It talks to all the lower level DLLs to get its work done.

Sajava.jar: This is the Java side of our Java JNI interface. This allows Java programs to easily call Java classes to interface to our Business Logic Views. For more on this interface see this article.

A4wcomsv.dll: This is the main workhorse for the COM and .Net APIs. It does all the heavy lifting and interfacing to the core DLLs.

Accpac.Advantage.COMSVR.Interop.dll: This just performs the .Net to COM transition which is created by the MS tools.

Accpac.Advantage.Server.dll: Server side of the .Net API, handles the .Net Remoting requests if remotely called or just passes through otherwise.

Accpac.Advantage.Types.dll: Defines all the various types we use in our .Net API.

Accpac.Advantage.dll: This is the main external interface for our .Net API. For more on our .Net API see the series of articles starting with this one.

A4wcomexps.dll: Used when the VB UIs are going to talk .Net Remoting, this DLL is inside a4wcomex.cab.

A4wcomex.dll: The main entry point for the COM API.

Many More DLLs

There are many more DLLs in the Sage 300 runtime, but most of the others are for obsolete APIs  like the xapi, the older a4wcom COM API, the cmd API, the icmd API, etc. There are other important ones like to do with Database Setup, but these are the main ones used when you talk to the Business Logic through one of the main popular APIs.

Summary

For anyone interested this should give you a good idea of what the main DLLs in the runtime folder do. And give you an idea of how the various services in Sage 300 ERP are layered.

Advertisements

Written by smist08

February 8, 2014 at 5:19 pm

Launching Non-SDK Programs From the Desktop

with 21 comments

launch

Introduction

When SDK applications are launched from the Desktop, they are passed an object handle that they can use to create a session that exactly matches the session of the desktop that launched them. Further the desktop can manage these programs and for instance put up an error message if you try to close the Desktop while they are still running.

Quite a few people create programs that aren’t written using our SDK, but still are tightly integrated to Sage 300 ERP via one of our APIs such as the COM API, .Net API or Java API. You can add arbitrary EXE programs to the Desktop as icons and launch them just like any other screen.

When we designed the current UI framework, we had the intention that our UIs could be run from many places, such as VBA macros or hosted inside Internet Explorer. We also envisioned them being strung together in workflow type applications. Towards this we created the Session Manager and the Signon Manager to help tie together programs running inside the desktop with programs running outside the desktop. For information on using the Session Manager, check out this blog posting.

Generally this has worked quite well. Especially if you only signon to one company, then all the various things running will share the same session and you won’t have to signon to everything separately. However there are a few limitations to our current approach. If there are two desktops running (usually signed on to different companies) then when the external program is run, it has to present a dialog to choose which company’s session to use. This makes sense if you say start an EXE program from the start menu, since how would it know which desktop session to use? But when you run from the desktop you would expect it to just use that desktop’s session, rather than being treated like it wasn’t run from the desktop. Similarly if you started an EXE program from the desktop you would expect the Desktop to prevent closing until this program is closed, right now this check is only for SDK programs run from the desktop and doesn’t apply to anything else.

A lot of people are creating standalone EXE’s that use our APIs and they are using the Session Manager, which generally works well, but would like to get the other cases handled as nicely. So for the upcoming Sage 300 ERP 2014 release we have added some support to the Desktop to help with this. To basically allow non-SDK programs to start with the same protocol as the SDK programs so they can behave in the same manner. The alpha (developer) early release of Sage 300 ERP 2014 is available to ISVs so you can try this out now.

New Macro Substitution

If you add a program to a groupfile or if you add a program via file new in the desktop, if you specify $objecthandle$ as an argument, then this will be translated into an object handle when you are run that you can use in other API calls to get a session that matches your desktop. For instance in a group file:

[ PROGRAM ]
ID = "XX0500"
PARENT = "XX0000"
DESCRIPTION = "test ojbect key"
CMDLINE = "c:\\accpac6\\sm\\testobj\\testobj.exe $objecthandle$"
RSC = "XXSDK"

 

This is then the token you can use to create your session exactly from the Desktop that ran you.

If you aren’t an SDK program, you probably don’t have your own group file. However you can use a couple of SDK tools to add your item to an existing group file. The program unccgrp.exe (usually installed in c:\pluswdev\bin) will de-compile a group file (these are usually grp.dat files in a programs language folder, like ar62a\eng\grp.dat). Then you can add your own entries to this and then use ccgrp.exe to re-compile the group file. This is a bit of a kludge because it may overwritten by Product Updates and two people trying to do this at once may collide and interfere with each other. But it can be an effective and useful technique.

How to Use the Object Handle

You can then pass the object handle into a session init call and your session will be configured to match the desktop you are run from. Additionally if you want to register your windows handle, you can use the roto api to do so given the object handle. You should also clear this when you terminate.

Below is a VB program which does these things. It uses the session it gets to display the company name in a label. This way it will be connected to the right Desktop and the Desktop knows when it’s running.

Private Declare Sub rotoSetObjectWindow Lib "a4wroto.dll" (ByVal objectHandle As Long, ByVal hWnd As Long)
Dim strObjectHandle As String

Private Sub Command1_Click()
    Unload Me
    '
    ' clear our window handle when closing so we don't block the desktop closing
    '
    rotoSetObjectWindow Val(strObjectHandle), 0
End Sub

Private Sub Form_Load()
    Dim mSession As New AccpacCOMAPI.AccpacSession

    '
    ' Get the object handle from the command line
    '
    strObjectHandle = Command$

    MsgBox "Object Handle = " + strObjectHandle

    '
    ' Use the object handle to intialize the session. With this you will inherit
    ' an open session matching the desktop that launched you.
    '
    mSession.Init strObjectHandle, "XY", "XY1000", "62A"

    '
    ' Set the window handle so the desktop can track whether you have closed
    ' effectively doing a roto openok.
    '
    rotoSetObjectWindow Val(strObjectHandle), Me.hWnd

    Dim mDBLinkCmpRW As AccpacCOMAPI.AccpacDBLink
    Set mDBLinkCmpRW = mSession.OpenDBLink(DBLINK_COMPANY, DBLINK_FLG_READWRITE)

    Dim CSCOM As AccpacCOMAPI.AccpacView
    Dim CSCOMFields As AccpacCOMAPI.AccpacViewFields
    mDBLinkCmpRW.OpenView "CS0001", CSCOM
    Set CSCOMFields = CSCOM.Fields

    CSCOM.Fetch
    Label1.Caption = CSCOMFields("CONAME").Value

End Sub