AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Thema durchsuchen
Ansicht
Themen-Optionen

C# callback von Delphi-dll

Ein Thema von bert7 · begonnen am 3. Feb 2010 · letzter Beitrag vom 6. Feb 2010
Antwort Antwort
bert7

Registriert seit: 31. Jan 2010
3 Beiträge
 
#1

C# callback von Delphi-dll

  Alt 3. Feb 2010, 07:40
hallo,

im Rahmen einer C#-Anwendung soll eine Delphi-dll eine C#-Methode mit Parametern aufrufen, also ein "callback" Thema.
Dazu wird von der C# Anwendung die aufzurufende C#-Funktion in der Delphi-Dll registriert, ein Funktionspointer ("delegate") übergeben. Dazu wird noch ein Testparameter übergeben.

Der testparamter wird korrekt nach Delphi übertragen, aber beim Aufruf der callback -Methode von Delphi aus nach C# klappts nicht:
In C# kommt irgendein 8-stelliger Zufallswert an, meistens derselbe, aber nicht immer.

Hier der Code der Delphi-dll:

Code:

type TCallback = procedure(val: integer);
var callback : TCallback;



procedure RegisterCallback(aCallback : TCallback; value: integer); stdcall;
begin
  callback:= aCallback; // registrieren...
  ShowMessage('In Delphi:'+ IntToStr(value)); // erfolgreich wird "10" ausgegeben

  callback(value); // ...und gleich testen
end;

exports
  RegisterCallback;
Und hier der C#-Code

Code:

    public partial class Form1 : Form
    {
        public delegate void ProcDelegate(int value);

        [DllImport("DLLTest.dll", CallingConvention = CallingConvention.StdCall)]
        public static extern void RegisterCallback(ProcDelegate callBackHandle, int value);


        public Form1()
        {
            InitializeComponent();

            RegisterCallback(CalledFromDelphi,10);// in delphi registrieren, "10" als test mitgeben

        }

        public static void CalledFromDelphi(int value)
        {
            MessageBox.Show("Wert:" + value); // kommt leider nicht "10" an, sondern ein "Zufalls?"-Wert

        }
    }
Erwähnenswert ist noch dass die Messagebox in C# zweimal aufgerufen wird, beidesmal mit großen "Zufalls?"-zahlen, obwohl offensichtlich der callback nur einmal von Delphi aus aufgerufen wird.

Weiss leider nicht , auf welcher Seite die Fehler liegen, vermutlich eher auf C#-Seite ?

Danke.
Bert
  Mit Zitat antworten Zitat
Chris.R

Registriert seit: 8. Sep 2009
Ort: Nürnberg
68 Beiträge
 
Delphi 2010 Professional
 
#2

Re: C# callback von Delphi-dll

  Alt 3. Feb 2010, 08:54
Hallo,

kannst du nicht über ein Interface, dass die C# Anwendung herausgibt einen Callback realisieren?

Ciao Chris
Guten Morgen! … Und falls wir uns heute nicht mehr sehen, Guten Tag, Guten Abend und Gute Nacht!
  Mit Zitat antworten Zitat
Benutzerbild von Phoenix
Phoenix
(Moderator)

Registriert seit: 25. Jun 2002
Ort: Hausach
7.606 Beiträge
 
#3

Re: C# callback von Delphi-dll

  Alt 3. Feb 2010, 09:34
Die CallingConvention des Callbacks ist falsch. Auch der müsste Stdcall sein. C# erlaubt Dir blöderweise nicht, auf der Callback-Methode die Calling Convention festzulegen.

Eine Lösung für VB(native) gibt es hier:
http://www.codeproject.com/KB/dotnet...CSharp_VB.aspx
Die kannst Du analog anpassen. Weitere Details siehe hier.

Viel Erfolg.
Sebastian Gingter
Phoenix - 不死鳥, Microsoft MVP, Rettungshundeführer
Über mich: Sebastian Gingter @ Thinktecture Mein Blog: https://gingter.org
  Mit Zitat antworten Zitat
bert7

Registriert seit: 31. Jan 2010
3 Beiträge
 
#4

Re: C# callback von Delphi-dll

  Alt 6. Feb 2010, 10:35
hallo,

sorry für die verspätete reaktion (dachte die email-benachrichtiging ist aktiv).

@Phoenix: danke für die Links, aber die beziehen sich anscheinend auf .NET 1.1.

Wie ich herausgefunden habe, gibt es ab .NET 2.0 das Attribut:

[UnmanagedFunctionPointer(CallingConvention.StdCall )]
public delegate void ProcDelegate(int value);

Habe jetzt bei RegisterCallback u. bei ProcDelegate beides je mit "Cdecl" und "StdCall" probiert. Bei "StdCall" beendet die Anwendung mit Zugriffsverletzung (0x0000005), bei "Cdecl" nicht. Doch bei beiden kommt nach wie vor eine falsche Zahl in C# an.

@Chris.R: Was würden mir Interfaces bringen bzw. was ändert das bei der Callback Registrierung bzw. am korrekten Aufruf von der dll aus ?

Bert
  Mit Zitat antworten Zitat
Benutzerbild von Khabarakh
Khabarakh

Registriert seit: 18. Aug 2004
Ort: Brackenheim VS08 Pro
2.876 Beiträge
 
#5

Re: C# callback von Delphi-dll

  Alt 6. Feb 2010, 11:59
Afaik benutzt P/Invoke beim Marshallen von Delegates standardmäßig bereits stdcall. Hast du denn auch TCallback als stdcall deklariert?
Und ich glaube nicht, dass es in diesem Fall technisch möglich ist , aber wenn die Delphi-DLL den Funktionszeiger länger behalten will, musst du auf C#-Seite den delegate vor dem GC schützen:
Code:
var callback = new ProcDelegate(CalledFromDelphi);
RegisterCallback(CalledFromDelphi,10);
GC.KeepAlive(callback);
Sebastian
Moderator in der EE
  Mit Zitat antworten Zitat
bert7

Registriert seit: 31. Jan 2010
3 Beiträge
 
#6

Re: C# callback von Delphi-dll

  Alt 6. Feb 2010, 13:25
Jetzt läufts !

Khabarakh, das war der entscheidende Tip: hatte "stdcall" hinter TCallback vergessen!

type TCallback = procedure(val: integer); stdcall; Und statt
Code:
GC.KeepAlive(procDelegate);
verwende ich ne statische Referenz:

Code:
public static ProcDelegate procDelegate;
und dann

Code:
procDelegate = new ProcDelegate(CalledFromDelphi)
RegisterCallback(procDelegate, 10);
Danke
Bert
  Mit Zitat antworten Zitat
Antwort Antwort


Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 01:18 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz