问题
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:
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);
}
}
来源:https://stackoverflow.com/questions/17578527/net-dll-needs-to-receive-a-clarion-callback-procedure-and-then-all-it-passing-t