Search code examples
c#.netcallbackclarion

.NET DLL needs to receive a Clarion callback procedure and then all it passing three ints?


I'm writing a C# .NET DLL for a Clarion (Clarion is C++ like programming language) program.

I call into the C# .NET DLL just fine, all is working great. However, I need that C# .NET DLL to receive a Clarion Procedure for callback purposes and then be able to call that procedure passing three int parameters.

The Clarion Procedure looks like this (a Clarion long is a C# int):

MyCallBack procedure(long p1, long p2, long p3)
... Data ...
    code
    ... Code ...

How do I pass the abvoe procedure to the C# .NET DLL and how does the C# .NET DLL call that procedure passing three int parameters?

Thanks in advance.


Solution

  • Hopefully this example gives you somewhere to start, it is based on an example from the SoftVelocity newsgroups (cached plain text version here).

    Note: I am using the RGiesecke DllExport package and a modified version of the Clarion LibMaker to create a compatible lib file. You mentioned that you are already calling into the C# DLL without issue so I am assuming that you are doing something similar. If you are interested, I go into this further on my blog.

    Clarion Code

      PROGRAM
      MAP
        MODULE('ManagedCSharpDLL.dll')
    CallbackProc                PROCEDURE(BSTRING PassedValue, *BSTRING ReturnValue),TYPE,PASCAL,DLL(TRUE)
    SetCallback                 PROCEDURE(*CallbackProc pCallback),NAME('SetCallback'),PASCAL,RAW,DLL(TRUE)
    TestCallback                PROCEDURE(*CString passedString),NAME('TestCallback'),PASCAL,RAW,DLL(TRUE)
        END
    Callback                PROCEDURE(BSTRING PassedValue, *BSTRING ReturnValue),PASCAL
      END
    a                   CSTRING(20)
    
    CODE
      Message('Clarion: SetCallback(Callback)')
      SetCallback(Callback)
    
      a = 'Call Test Worked'
      Message('Clarion: Send message: ' & a)
    
      TestCallback(a)
    
      Message('Clarion: Made call and got back safely')
    
    Callback      PROCEDURE(BSTRING PassedValue, *BSTRING ReturnValue)
    
      CODE
        MESSAGE('Clarion: Passed Value: ' & PassedValue)
        ReturnValue = 'Done'
    

    C# Code

    using System;
    using System.Runtime.InteropServices;
    using System.Windows.Forms;
    using RGiesecke.DllExport;
    
    namespace ManagedCSharpDLL
    {
      public static class UnmanagedExports
      {
    
        private static CallbackProc _callback;
    
        [DllExport("SetCallback", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
        public static void SetCallback(CallbackProc pCallback)
        {
          _callback = pCallback;
          MessageBox.Show("C#: SetCallback Completed");
        }
    
        [DllExport("TestCallback", CallingConvention = System.Runtime.InteropServices.CallingConvention.StdCall)]
        public static void TestCallback(string passedString)
        {
          string displayValue = passedString;
          string returnValue = String.Empty;
    
          MessageBox.Show("C#: About to call the Callback. displayValue=" + displayValue + ", returnValue=" + returnValue);
          _callback(displayValue, ref returnValue);
          MessageBox.Show("C#: Back from the Callback. displayValue=" + displayValue + ", returnValue=" + returnValue);
        }
    
        public delegate void CallbackProc( [MarshalAs(UnmanagedType.BStr)] String PassedValue,  [MarshalAs(UnmanagedType.BStr)] ref String ReturnValue);
    
      }
    }