Calling Clarion 6.3 .dll from Windows Form Application C#

I’ve been studying a few Clarion tutorials and also reading the suggested post from below.

The current way of opening my Clarion application is our C# code would execute a StartProcess for command line with the args such as Database, Data server, etc. The C# code calls StartProcess on a Clarion .exe (DMX.EXE).

Instead of the current method I’d like to use P\invoke. It’s cleaner and a better way to address interop between Clarion and .Net.

First - I’ll need to change the Clarion DMX.exe to a .dll in application settings. This will allow me to export the procs I’ll need for pinvoke. I’ll call Clarion with the code below from my .net application.

  public class CALLClarion
{
[DllImport(@"C:\IBSSQL\DMCommon.dll")]
public static extern void ConnectToDbAndShowTask([param: MarshalAs(UnmanagedType.BStr)]  string pMyConnect);
}

Second -Pass the args as BSTRING from C# using P/Invoke to the new DMX.dll

Third - Separate the string and store them as Global Variables…

Once I get here I"ll update again.

1 Like

I am guessing that by the time your Clarion application gets to calling ShowMyTasks() it has already dealt with the database connection. If you call ShowMyTasks() directly from .NET then you have skipped that. Maybe you can create a ConnectToDbAndShowMyTasks() in Clarion that you can call from .NET?

Ok, so perhaps in this case what you want to do is have the bit where the Clarion application opens yours send over a callback procedure reference.
Are you able to alter the Clarion application at all?

See, if you can communicate via a callback then you are telling the running application to “do something” instead of [DllImport] which just loads (I assume similar to LoadLib) the DLL and calls the procedure “cold”.

Maybe this will give you some hints:

So your Clarion application is running the .NET EXE, like Process.Start() kind of thing. This means that they are two separate windows processes and are no longer connected.

This doesn’t mean they cannot communicate but you will have to decide how to best achieve that communication.

If I have the terminology right you want to be looking into either “interop” or “interprocess” communication.

I have already spoken to @BryanGerre on how to get this to work, but for the record, here goes.

To pass strings to clarion from .Net you will need to marshal them as BSTRINGS, this can be done by Changing Bryans C# as follows.

public class CALLClarion
{
    [DllImport(@"C:\IBSSQL\DMCommon.dll", EntryPoint = "ConnectToDbAndShowTask")]

    public static extern void ConnectToDbAndShowTask([param: MarshalAs(UnmanagedType.BStr)]  string pMyConnect);

}

You will notice the meta parameter marshalling going on here, instructing .Net to marshal any string passed to this procedure as a BStr. [param: MarshalAs(UnmanagedType.BStr)]

On the clarion side the prototype for the method needs to be as follows.

(BSTRING pMyConnect),PASCAL,NAME('ConnectToDbAndShowTask')

As you can see we are using a Clarion BSTRING to accept the value passed in. Also the PASCAL calling convention attribute.

You will note I have used the clarion NAME parameter to specify the external name of the procedure. This stops the Name Mangling in the export in the DLL.

A side note is that if you are going to prototype the procedure in .Net with the same name as the procedure in the clarion DLL and you have used the NAME parameter with the same name also, then the EntryPoint meta data is not required.

So if this was the case, then the final prototype on the .Net side would become

public class CALLClarion
{
    [DllImport(@"C:\IBSSQL\DMCommon.dll")]
    public static extern void ConnectToDbAndShowTask([param: MarshalAs(UnmanagedType.BStr)]  string pMyConnect);
}
1 Like

Worked perfect ! thanks for your time.