Laden...

Callback in c# für c++ setzen

Erstellt von Ifoko vor 18 Jahren Letzter Beitrag vor 18 Jahren 3.012 Views
I
Ifoko Themenstarter:in
256 Beiträge seit 2005
vor 18 Jahren
Callback in c# für c++ setzen

Hallo!

Ich habe ein c# und ein c++ Programm. Beide verwaltet.

In c++ habe ich folgende Struktur

 public __value struct SCAN_INIT
{
    int   lsCanPort;       // CAN Karte Port Nummer 
    int   lsHostIdBase;    // Lasersensor Host ID Base
    int   lsSensorIdBase;  // Lasersensor ID Base
    int   lsSensorId;      // Lasersensor ID
    bool  syLoggingActive; // wenn true logging ON
    SCAN_EC ( *syScanDrvCallBackFnc) (int mvNum); // drv callBack Funktion
};

public __value  enum SCAN_EC
{
    SCAN_EC_OK = 0,                      // Alles OK kein Fehler
    SCAN_EC_RU_INIT = 1,                 // Fehler bei der Initialisierung des Motor Treibers
    SCAN_EC_RU_NOT_HOME = 2,             // Der Motor ist nicht home gefahren worden
    SCAN_EC_RU_TIMEOUT_MOTION_END = 3,   // timeOut Motorbewegung
    SCAN_EC_RU_TIMEOUT_MOTION_HOME = 4,  // timeOut bei der home-
};

Wie muss ich jetzt die SCAN_EC ( *syScanDrvCallBackFnc) (int mvNum) Callback in c# definieren damit ich sie in die Struktur stellen kann?

lg

4.506 Beiträge seit 2004
vor 18 Jahren

Hallo Ifoko!

Wenn ich das jetzt richtig interpretiert habe (C++ ist doch schon länger her 😉, dann bedeutet die Zeile:



SCAN_EC ( *syScanDrvCallBackFnc) (int mvNum);


ungefähr dem C# Methodenrumpf:



public SCAN_EC MeineMethode(int mvNum)
{}


Dabei kannst Du ja folgendermaßen vorgehen:

  • SCAN_EC muss Deiner C#-Klasse als Struct auch bekannt sein, das müsste von managed C++ dann einfach importierbar sein (über namespace->C++Klasse->Struct SCAN_EC)

  • Die Methode sollte in C# so implementiert sein wie oben gezeigt.

  • Das SCAN_INIT Struct sollte dann ein Delegat auf diese Methode enthalten.

Delegat erzeugen:



public delegate SCAN_EC delegateMeineMethode(MeineMethode);


Für die Verwendung des SCAN_INIT kannst Du das folgendermaßen tun:



myNamespace.C++Klasse.SCAN_INIT myStruct = new myNamespace.C++Klasse.SCAN_INIT();

myStruct.syScanDrvCallBackFnc = new delegateMeineMethode(myIntValue);


Das sollte es gewesen sein.

Bitte vorher selbst n bischen ausprobieren, denn ich hab das hier im Texteditor entwickelt und nicht getestet.

Aber auf jeden Fall sollte es Dich weiterbringen.

Ciao
Norman-Timo

A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”

I
Ifoko Themenstarter:in
256 Beiträge seit 2005
vor 18 Jahren

Danke vorerst!

Leider funktioniert es nicht ganz.

	public SCAN_EC MeineMethode(int mvNum)
		{
			return SCAN_EC.SCAN_EC_OK;
		} 
		public delegate SCAN_EC delegateMeineMethode(SCAN_EC MeineMethode); 
        
        // ********************** SCAN *****************************************
        private void button_start_scan_click(object sender, System.EventArgs e)
        {
            SCAN_Cdrv scanDrv = new SCAN_Cdrv();
            
            SCAN_EC ec;

            
            SCAN_INIT ini = new SCAN_INIT(); 
            
            ini.ruMinPosDeg = -90;          //(int)   ru neg. Wert des ru Begrenzungsschalters [-90..0[ (HW Limit !!!!)
            ini.ruMaxPosDeg = 90;           //(int)   ru pos. Wert des ru Begrenzungsschalters ]0..90]  (HW Limit !!!!) 

			ini.syScanDrvCallBackFnc = new delegateMeineMethode(10) ;
 

Ich bekomme beim compilieren

E:\RHI\ConScanC#\CK temp\temp\cs_lib_test\Form1.cs(207): 'syScanDrvCallBackFnc' wird von der Sprache nicht unterstützt
 
 
[Compiler Error CS0570]

"Klasse" verweist auf einen Typ, der von der Sprache nicht unterstützt wird

Dieser Fehler tritt auf, wenn importierte Metadaten verwendet werden, die durch einen anderen Compiler erzeugt wurden. Der Code hat versucht, einen Klassenmember zu verwenden, den der Compiler nicht verarbeiten kann.


weil von meiner c++ SCAN_INIT Struktur

 public __value struct SCAN_INIT
{
    int   ruMinPosDeg;     // Motor Begrenzungsschalters Minimum >= SCAN_RU_ABS_NEG_MOTOR_LIMIT_DEG 
    int   ruMaxPosDeg;     // Motor Begrenzungsschalters Maximum <= SCAN_RU_ABS_POS_MOTOR_LIMIT_DEG

    bool  syLoggingActive; // wenn true logging ON
    SCAN_EC ( *syScanDrvCallBackFnc) (int mvNum); // drv callBack Funktion
};

kennt er syScanDrvCallBackFnc nicht im c#
Kennt wer ein Bsp ?

lg ifoko

I
Ifoko Themenstarter:in
256 Beiträge seit 2005
vor 18 Jahren

Hallo hat jemand ein Bsp. wo ich von c# eine callback in c++(dll) definiere und übergebe.
Beides managed.

Ich find leider nix passendes. Mein Problem, ich seh die "Callback definition" vom c++ nicht im c#.

lg ifoko

4.506 Beiträge seit 2004
vor 18 Jahren

Hallo Ifoko!

Boah! Jetzt bin ich aber wirklich enttäuscht von managed irgendwas.

Das "*syScanDrvCallBackFnc" bedeutet ja, dass ein Pointer auf eine Funktion erzeugt wird. Dieser Pointer müsste rein theoretisch einer echten instanziierten Methode zugewiesen werden, deshalb meine Vermutung mit dem delegate. Dass das aber jetzt nicht importierbar sein soll, da bin ich aber von .NET etwas enttäuscht.

Den C++ -Quellcode kannst Du nicht ändern? (Naja ich wüsste im ersten Moment auch gar nicht wie das dann funktionieren sollte.

Oder vielleicht den C++ Code als Dll kompilieren und per DLL-Import im C# einbinden?

Das sind jedoch nur allerletzte Versuche, die nicht viel Methodik aufweisen, nur Try-And-Error.

Sorry, da bin ich zumindest überfragt (werd das aber weiterverfolgen)...

Ciao
Norman-Timo

A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”

I
Ifoko Themenstarter:in
256 Beiträge seit 2005
vor 18 Jahren

Hallo Norman!

Den c++ Code kann ich frei ändern. Die Callback muss auch nicht in dieser Struktur vorhanden sein, kann sie auch übergeben.

Ich muss irgendwie eine c# callback ins c++ reinbekommen.

lg ifoko

4.506 Beiträge seit 2004
vor 18 Jahren

Hallo Ifoko!

Mach doch dann mal ein Testprojekt in C# auf. Dann eine Methode entwerfen, die als Parameter einen delegate enthält.

Diesen Code Compilieren.

Dann ein C++ managed Testprojekt, das die C# Methode mit einbindet. Dann kannst Du Rückschlüsse draus ziehen, was in C++ erstellt werden muss, um in C# delegates zu verwenden.

Also sozusagen durch die Brust ins Auge 😉

Ciao
Norman-Timo

A: “Wie ist denn das Wetter bei euch?”
B: “Caps Lock.”
A: “Hä?”
B: “Na ja, Shift ohne Ende!”

Q
992 Beiträge seit 2005
vor 18 Jahren

Schau doch mal hier:

http://www.mycsharp.de/wbb2/thread.php?threadid=8374

Oder hier, Besonders der Link im letzten beiträg ist interessant.

http://www.mycsharp.de/wbb2/thread.php?threadid=6084

Edit: Ich weiß nicht ob dir das bei der Kommunikation mit verwaltetem C++ hilft.

I
Ifoko Themenstarter:in
256 Beiträge seit 2005
vor 18 Jahren

So ich bin inzwischen ein bissl weitergekommen.
Ist vielleicht doch nicht so kompliziert die Sache, wenn man weis wies geht 😜

Der C# Code für die Defintionen


		public SCAN_EC MeineMethode(int mvNum)
		{
			return SCAN_EC.SCAN_EC_OK;
		} 
		public delegate SCAN_EC delegateMeineMethode(int mvNum); 
    
		[DllImport("scan.dll")]
		public static extern SCAN_EC SetCallBackFunction (delegateMeineMethode methode);


Der Aufruf

 			delegateMeineMethode mydelegate = new delegateMeineMethode(this.MeineMethode);
		
			SetCallBackFunction(mydelegate);


Im C++ nur folgendes

 extern "C" __declspec(dllexport) void SetCallBackFunction (SCAN_EC(*callFunction)( int mvNum))
{
    callFunction (10);        //aufrufen
}

Hupft im Debugger schön hin und her.
Es dürfte funktionieren aber warum genau, keine Ahnung.
Unklar ist mir noch immer was __declspec usw. bedeutet.

Bitte weiter posten, da das Thema mir wichtig erscheint und es fast keine (verstehbare) Doku gibt.

lg ifoko

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Ifoko,

guckst du

http://msdn.microsoft.com/library/default.asp?url=/library/en-us/vccelng/htm/msmod_17.asp

(erster Treffer bei googlen nach __declspec)

herbivore

I
Ifoko Themenstarter:in
256 Beiträge seit 2005
vor 18 Jahren

Danke für die Mühe!

Das ist genau mein Problem 😄, Schöner englischer Text, ohne jahrelange tiefe MS C Kenntnisse nicht zu verstehen.(zumindest ich).

lg ifoko

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Ifoko,

__declspec ( extended-decl-modifier-seq )

Note that extended-decl-modifier-seq can be empty; in this case, __declspec has no effect.

Jetzt klarer? 🙂

herbivore

I
Ifoko Themenstarter:in
256 Beiträge seit 2005
vor 18 Jahren

Sers!

Nö leider nix.

lg ifoko

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Ifoko,

sorry, ich hatte Tomaten auf den Augen. So jetzt nochmal das richtige:

The dllexport [...] storage-class attributes are Microsoft-specific extensions to the C and C++ languages. They enable you to export and import functions, data, and objects to and from a DLL. These attributes explicitly define the DLLs interface to its client, which can be the executable file or another DLL. Declaring functions as dllexport eliminates the need for a module-definition (.DEF) file, at least with respect to the specification of exported functions. Note that dllexport replaces the __export keyword.

Jetzt klarer? 🙂

herbivore

I
Ifoko Themenstarter:in
256 Beiträge seit 2005
vor 18 Jahren

Sers!

Ich glaub es bringt nicht viel hier englische Textauzüge zu posten.

Erkläre mal die ganze Sache auf DEUTSCH und LEICHT verständlich

lg

Q
992 Beiträge seit 2005
vor 18 Jahren

Original von Ifoko
Sers!

Ich glaub es bringt nicht viel hier englische Textauzüge zu posten.

Erkläre mal die ganze Sache auf DEUTSCH und LEICHT verständlich

lg

Bitteschön g :

Die Ablage-Kategorienattribute des dllexport [... ] sind Microsoft-spezifische Verlängerungen zu den c- und C++-Sprachen. Sie ermöglichen Ihnen, Funktionen, Daten und Gegenstände nach und von einem DLL zu exportieren und zu importieren. Diese Attribute definieren ausdrücklich die Schnittstelle DLLs zu seinem Klienten, der die vollziehbare Akte oder eine anderen Funktionen DLL. Declaring sein kann, während dllexport die Notwendigkeit an einer Akte der Modul-Definition (DEF) beseitigt, mindestens in Bezug auf die Spezifikation der exportierten Funktionen. Merken Sie, daß dllexport das __exportschlüsselwort ersetzt.

49.485 Beiträge seit 2005
vor 18 Jahren

Hallo Ifoko,

naja, der Textauszug sagt es für meine Begriffe aber ziemlich auf den Punkt. Und Englisch brauchst du für's Programmieren m.E. sowieso. Da kann man sich dann auch mal versuchen durchzubeissen.

Anyway:

Wenn man eine Funktion/Methode im Code definiert, der in eine DLL compiliert wird, kann man die Methoden nicht automatisch von außen aufrufen. Für die Methoden, die man von außen aufrufen können möchte schreibt man __declspec(dllexport). Damit wir die entsprechende Methode von der DLL exportiert, quasi Teil ihrer Schnittstelle und ist dann von außen aufrufbar.

herbivore