Delphi and C#, Implementing Callback functions

J

Jon E. Scott

I've got a project where I need to create a C# project and a Delphi DLL, in
which the DLL has a callback function to send statuses back to the C#
application. It seems pretty straightforward in a MSDN example in which it
explains the use of delegates
(http://msdn2.microsoft.com/en-us/library/843s5s5x.aspx), but for some
reason I get an AccessViolationException when the callback function is
called. Anyone have any ideas? Here's the Delphi DLL:

library Project1;

uses
SysUtils,
Classes;

{$R *.res}

type
TTestProc = procedure(TestInt: integer) of object;

function TestCallBack(CallBack: TTestProc): boolean; stdcall;
begin
CallBack(12345);
Result := True;
end;

exports
TestCallBack;

end.

Then the C# project:

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using System.Runtime.InteropServices;

namespace WindowsApplication1
{
public partial class Form1 : Form
{
private delegate void CallBack(int testParam);

[DllImport("N:\\Temp\\Project1.dll")]
private static extern bool TestCallBack(CallBack x);

public Form1()
{
InitializeComponent();
}

private void button1_Click(object sender, EventArgs e)
{
CallBack myCallBack = new CallBack(Form1.Report);
TestCallBack(myCallBack); //<-- AccessViolationException here
}

private static void Report(int testParam)
{
MessageBox.Show(testParam.ToString());
}
}
}
 
B

Barry Kelly

Jon said:
I've got a project where I need to create a C# project and a Delphi DLL, in
which the DLL has a callback function to send statuses back to the C#
application.
type
TTestProc = procedure(TestInt: integer) of object;

This is a Delphi method pointer, and therefore has an implicit 'Self'
argument. Also, it is not declared to use the 'stdcall' calling
convention.

You should try something more like:

type
TTestProc = procedure(TestInt: Integer) stdcall;
function TestCallBack(CallBack: TTestProc): boolean; stdcall;
begin
CallBack(12345);
Result := True;
end;
private delegate void CallBack(int testParam);

This is a .NET delegate, and the P/Invoke marshalling layer of .NET
handles it as a simple function pointer, with no implied 'Self'
argument.
[DllImport("N:\\Temp\\Project1.dll")]
private static extern bool TestCallBack(CallBack x);

Finally, for questions which need Delphi-specific knowledge, you're
probably better off asking on the Delphi newsgroups, currently at
nntp://newsgroups.borland.com/.

-- Barry
 
J

Jon E. Scott

"Barry Kelly wrote...
This ought to be:

type
TTestProc = procedure(TestInt: Integer) stdcall;

Yup, that's where the problem was. Changed that line and the callback
functions work!

Thanks for your help.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top