.NET DLL needs to receive a Clarion callback proce

2019-05-21 21:50发布

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.

1条回答
叼着烟拽天下
2楼-- · 2019-05-21 22:39

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);

  }
}
查看更多
登录 后发表回答