tutorials.de Buch-Aktion 05/2012
ERLEDIGT
JA
ANTWORTEN
4
ZUGRIFFE
5253
EMPFEHLEN
  • An Twitter übertragen
  • An Facebook übertragen
AUF DIESES THEMA
ANTWORTEN
  1. #1
    xMen xMen ist offline Mitglied Bronze
    Registriert seit
    Apr 2004
    Beiträge
    35
    Hallo C#-User,

    ich habe erneut ein Problem mit der Umsetzung bzw. Nutzung einer DLL-Funktion. Diesmal mit der Übergabe einer Struktur. Die Funktionsbeschreibung der DLL-Funktion lautet im Original:

    Code :
    1
    
    short ExternDllFunction(char Parameter_1, Parameter_2 = Struktur* StrukturDefinition)

    Es wird als Parameter_2 also ein Pointer auf eine Struktur vom Typ "StrukturDefinition" erwartet. Leider habe ich bei der Umsetzung so meine Schwierigkeiten. Ich habe in C# die folgend Struktur erzeugt:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    
    /// Struktur 
            public struct myStructure
            {   
                public string para_1, para_2, para_3;
     
                public myStructure(string para_1, string para_2, string para_3)
                {
                    this.para_1 = value_1;
                    this.para_2 = value_2;
                    this.para_3 = value_3;              
                }
            }

    Ich habe folgende Fragen:

    1. Wie muss ich die externe Funktion deklarieren, damit als 2. Parameter eine Struktur vom Typ "StrukturDefinition" erwartet wird.

    2. Wie übergebe ich diese Struktur nun als 2. Parameter an die externe DLL-Funktion?

    Ich habe den Aufruf in der folgenden Form definiert, was natürlich falsch ist.

    Code :
    1
    2
    
    [DllImport("extern.dll", CharSet = CharSet.Ansi)]
    public static extern short ExternDllFunction(StringBuilder Parameter_1, StringBuilder Parameter_2);

    Der Aufruf funktioniert zwar, aber die Funktion liefert nicht das korrekte Ergebnis. Kann jemand helfen?
     
    jlo

    Das Leben ist zu kurz, um sich zu langweilen...

  2. #2
    Registriert seit
    Nov 2003
    Ort
    Bergen / Norway
    Beiträge
    309
    Mit der übergabe von Zeigern auf Strukturen hatte ich bis jetzt immer Probleme !
    Aber wenn jemand weiß wie das auch 100%ig funktioniert wäre das sehr gut !

    DarkGreetinx
     
    "Gott ist tot! Gott bleibt tot! Und wir haben ihn getötet." - Friedrich Nietzsche

  3. #3
    Avatar von Mobix
    Mobix Mobix ist offline Mitglied
    Registriert seit
    Dec 2004
    Beiträge
    19
    Die zu übergebende Struktur muss in C# erst so nachgebildet werden, wie die DLL das auch erwartet!

    Dazu solltest Du zunächst im StructLayout-Attribut festlegen, dass die Felder der Sturktur sequenziell im Speicher angelegt werden (ist bei -Net im Normalfall anders hab ich gelesen). Dazu ist im Konstruktor der Wert "LayoutKind.Sequential" zu setzen!
    Weiter sollten Strings mit MarshalAs deklariert werden.
    Code :
    1
    2
    3
    4
    5
    6
    7
    
    [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi)]
    public struct STRUCTFORDLL
    {
    public uint einfachtIntWert;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=1024)] public string string1;
    [MarshalAs(UnmanagedType.ByValTStr, SizeConst=1024)] public string string2;
    }
    Ob das MarshalAs in diesem Fall auch mit StringBuilder erstetzt werden kann glaube ich nicht, da dann die Größe ja variabel wäre und das dem Sinn einer Struktur weniger entspricht. Wenn hierzu jemand mehr sagen kann wäre ein Feedback nicht schlecht.

    Beim Import der DLL muss die Sturktur dann explizit mit ref deklariert werden wenn die Struktur in der DLL geändert bzw. mit Daten gefüllt werden soll:
    Code :
    1
    2
    
    [DLLImport ("deine.dll)]
    public statix extern int ExternDllFunction(char Parameter1, ref STRUCTFORDLL instanzDerStructur);

    Gruss

    Mobix
     
    Man muss die Welt nicht verstehen, man muss sich nur darin zurechtfinden. (A. Einstein)

  4. #4
    xMen xMen ist offline Mitglied Bronze
    Registriert seit
    Apr 2004
    Beiträge
    35
    Hallo Leute,

    also, ich habe am Wochenende ´mal einiges versucht. Hier meine Struktur:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    
    /// Struktur myStructure
    public struct myStructure
    {
            public string value_1;
        public string value_2;
        public string value_3;
        public string value_4;
    }

    Hier mein DLL-Aufruf. Es wird die Struktur als Pointer übergeben...

    Code :
    1
    2
    
    [DllImport("extern.dll", CharSet = CharSet.Ansi)]
    public static extern short GetMyTestData(string param_1, ref myStructure myStructure);

    Hier mein Aufruf der Methode:

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    
     
    private void button1_Click(object sender, System.EventArgs e)
    {
          string myParam_1 = "blabla";
     
          myStructure _myStructure = new myStructure();
          _myStructure.value_1 = new string(' ', 4) + "\0";
          _myStructure.value_2 = new string(' ', 11) + "\0";
          _myStructure.value_3 = new string(' ', 5) + "\0";
          _myStructure.value_4 = new string(' ', 17) + "\0";
     
          try
          {
              short returnCode = GetMyTestData(myParam_1, ref _myStructure);
                    
              if ( returnCode == 0 )
                  {
                         ....               
              }
              else
              {
                ....            
              }
          }
          catch ( Exception ex )
          {
              this._progInfo.Fehler(ex);
          }
    }

    Also, die Funktion ansich läuft! Aber sie liefert kein Ergebnis!

    Nun ist mir bekannt, dass ein Struktur ein vorgegebenes Muster hat. Die Struktur, die ich hier verwende, hat auch ein vorgeschriebenes Muster. Da ich aber auch weiß, dass für die Rückgabe von Werten aus einer externen DLL, keine Strings verwendet werden können und die Möglichkeit, die Struktur-Werte als StringBuilder zu übergeben ausgeschlossen ist, stehe ich erneut vor einem Rätsel, was ich dringend lösen muss.

    Es muss doch möglich sein, diese C++-Funktion mit C# korrekt aufrufen zu können und auch die Werte zurück zu bekommen, die lt. Funktion geliefert werden sollen...

    Hat jemand eine Idee?
     
    jlo

    Das Leben ist zu kurz, um sich zu langweilen...

  5. #5
    xMen xMen ist offline Mitglied Bronze
    Registriert seit
    Apr 2004
    Beiträge
    35
    Hallo Leute,

    nach einigem "Hin und Her" habe ich die Funktion nun endlich zum Laufen gebracht HURRA...

    Ursache des Fehlers in meinem Code war tatsächlich die "Art der Struktur" in C#. Da "C++"-Code unmanaged ist, brachte erst der Umweg über die [MarshalAS]-Methode das richtige Ergebnis.

    @Mobix: Danke für den Tipp ...


    Hier das Beispiel, welches nun tatsächlich funktioniert...

    Code :
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    
    /// Strukturdefinition ///
    public struct myStructure
    {           
         [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 10)] public string value_1;
         [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 31)] public string value_2;
         [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 64)] public string value_3;
         [MarshalAs(UnmanagedType.ByValTStr, SizeConst = 25)] public string value_4;
    }
     
     
    /// DLLImport ///
    [DllImport("extern.dll", CharSet = CharSet.Ansi)]
    public static extern short GetMyTestData(string param_1, out myStructure _myStructure);
     
     
    /// Aufruf der Methode ///
    private void button3_Click(object sender, System.EventArgs e)
    {
            /// param_1 muss lt. Beschreibung nullterminiert sein
        string param_1 = "blabla" + "\0";
     
        try
        {
                myStructure _myStructure;
            short returnCode = GetMyTestData(param_1, out _myStructure);
                    
            if ( returnCode == 0 )
            {                   
            }
            else
            {                   
            }
        }
        catch ( Exception ex )
        {
            this._progInfo.Fehler(ex);
        }
    }

    Ich hoffe, dass damit auch anderen geholfen ist, die das gleiche "nervige" Problem irgendwann einmal "haben werden"
     
    jlo

    Das Leben ist zu kurz, um sich zu langweilen...

Ähnliche Themen

  1. Struktur als Parameter im ActiveX Objekt
    Von Test im Forum Borland CBuilder und VCL
    Antworten: 0
    Letzter Beitrag: 30.06.10, 08:57
  2. Parameter an externe JS-Datei übergeben
    Von Moritz123 im Forum Javascript & Ajax
    Antworten: 5
    Letzter Beitrag: 18.02.10, 18:17
  3. Array als Parameter für eine Funktion
    Von maxi im Forum Visual Basic 6.0
    Antworten: 6
    Letzter Beitrag: 08.01.10, 07:33
  4. XML-Struktur an externe Swf übergeben
    Von OTurner im Forum Flash Plattform
    Antworten: 10
    Letzter Beitrag: 05.12.09, 14:25
  5. externe Parameter an Applet weitergeben
    Von sportingt im Forum HTML & XHTML
    Antworten: 2
    Letzter Beitrag: 21.10.05, 10:03