Autor Beitrag
I.c.h
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 20
Erhaltene Danke: 4

Win XP, Win 7
C# (VS 2010), Java, PHP
BeitragVerfasst: Do 14.07.11 21:31 
Hallo Forengemeinde,

ich brauche nochmal euern Rat:
ich habe in C eine DLL bekommen von der ich weiß, dass die fragliche Funktion so aussehen müsste:

ausblenden Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
char* encrypt (char* str_tocrypt)
{
  char* str_retval;

  /* mir unbekannter Bereich */
  
  return str_retval;
}


Ich muss zugeben DLLs, die in C geschrieben sind habe ich noch nie in C# eingebunden.
C kann ich nicht (wie gesagt die DLL habe ich so bekommen). Deshalb meine Frage: Wie mache ich C# klar, dass char* ein Ansi-String ist?

Schönen Abend noch...
I.c.h
Th69
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Moderator
Beiträge: 4799
Erhaltene Danke: 1059

Win10
C#, C++ (VS 2017/19/22)
BeitragVerfasst: Fr 15.07.11 10:38 
Hallo,

solange der String-Parameter nur gelesen wird (und nichts dort hineingeschrieben wird), kannst du einfach 'string' benutzen (ansonsten StringBuilder):
ausblenden C#-Quelltext
1:
2:
[DllImport("DLLNAME")]
public static extern string encrypt (string str_tocrypt);


Du kannst auch zusätzlich noch beim DllImportAttribute den Parameter 'CharSet' setzen (aber standardmäßig ist der von C# aus sowieso auf 'Ansi' gesetzt):
ausblenden C#-Quelltext
1:
2:
[DllImport("DLLNAME", CharSet=CharSet.Ansi)]
public static extern string encrypt (string str_tocrypt);

Für diesen Beitrag haben gedankt: I.c.h
I.c.h Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 20
Erhaltene Danke: 4

Win XP, Win 7
C# (VS 2010), Java, PHP
BeitragVerfasst: Sa 16.07.11 19:21 
So ich bin zurück! :wink:

Die Rückgabe habe ich inzwischen hinbekommen:
ausblenden C#-Quelltext
1:
2:
3:
4:
5:
6:
[DllImport("crypt.dll")]
        private static extern IntPtr encrypt(byte[] str_tocrpyt);

// ...

MessageBox.Show(Marshall.PtrToStringAnsi(encrypt(/*der Teil funktioniert noch nicht*/));


Die Paramterübergabe bereitet mir aber Bauchweh:
ich habe schätzungsweise alle Google-Ergebnisse der ersten 3 Googleseiten abgegrast und nichts hat funktioniert (Stringbuilder inklusive).
Die Exception die ich bekomme lautet:
Ein Aufruf an die PInvoke-Funktion "CS-Demo!CS_Demo.Form1::encrypt" hat das Gleichgewicht des Stapels gestört. Wahrscheinlich stimmt die verwaltete PInvoke-Signatur nicht mit der nicht verwalteten Zielsignatur überein. Überprüfen Sie, ob die Aufrufkonvention und die Parameter der PInvoke-Signatur mit der nicht verwalteten Zielsignatur übereinstimmen.

Wenn ich die Exception richtig deute verwende ich den falschen C#-Datentyp.

Hat jemand von euch einen Tipp?
I.c.h Threadstarter
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 20
Erhaltene Danke: 4

Win XP, Win 7
C# (VS 2010), Java, PHP
BeitragVerfasst: Sa 16.07.11 23:42 
So, zu später Stunde hat es doch noch funktioniert: Arbeite ich mit .Net 3.5 und niedriger statt mit 4.0 funktioniert alles wie's soll.
Da muss Microsoft wohl was rumgeschraubt haben!?

Vielen Dank für die Hilfe auf jeden Fall.
pdelvo
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starofftopic star
Beiträge: 55
Erhaltene Danke: 11



BeitragVerfasst: Mo 08.08.11 01:17 
Was ist denn die Fehlermeldung gewesen. Es war doch sicherlich die meldung "PInvokeStackImbalance", oder?

Wenn ja, ist das keine Fehlermeldung, sondern ein Hinweiß darauf, dass die Methodensignatur so nicht ganz korrekt ist. Vieleicht hilft es die CallingConvention festzulegen:

ausblenden C#-Quelltext
1:
2:
[DllImport("DLLNAME", CharSet=CharSet.Ansi, CallingConvention = CallingConvention.Cdecl)]
public static extern string encrypt (string str_tocrypt);