C#-Struktur als Parameter für eine externe DLL-Funktion ( C++ )

xMen

Mitglied
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:
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:
/// 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:
[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?
 
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
 
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:
[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:
[DLLImport ("deine.dll)]
public statix extern int ExternDllFunction(char Parameter1, ref STRUCTFORDLL instanzDerStructur);

Gruss

Mobix
 
Hallo Leute,

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

Code:
/// 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:
[DllImport("extern.dll", CharSet = CharSet.Ansi)]
public static extern short GetMyTestData(string param_1, ref myStructure myStructure);

Hier mein Aufruf der Methode:

Code:
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?
 
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:
/// 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"
 

Neue Beiträge

Zurück