Autor |
Beitrag |
Bronstein
      
Beiträge: 578
Erhaltene Danke: 1
WIN XP
Delphi 6 / Delphi 2006 / Delphi XE
|
Verfasst: Fr 23.01.15 15:19
Hallo ich habe eine Delphi Dll die folgendermaßen deklariert ist:
Delphi-Quelltext 1: 2:
| function GetInfosN(PW, Benutzer, Auftrag, Variante, werk, stueliHerkunft,strError, strLog, strTimes, strResult: PAnsichar; aPlan, stueli, matVerw, aNetz, klassfz: Boolean; NoXML: Boolean): Boolean; stdcall; |
In Delphi rufe ich diese folgendermaßen auf:
Delphi-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18:
| function GetInfosN(PW,Benutzer,Auftrag,Variante,werk,stueliHerkunft,strError,strLog,strTimes,strResult:PAnsichar; aPlan,stueli,matVerw,aNetz,klassfz: Boolean;NoXML: Boolean): Boolean; stdcall; external 'SAP_STUELI.dll' name 'GetInfosN'; ... const MAX_RESSTR_LEN = 6048576; MAX_LOGSTR_LEN = 100000; var tmpData,tmpTimes,tmpError,tmpLog:PAnsiChar; begin tmpData:=AnsiStrAlloc(MAX_RESSTR_LEN); tmpTimes:=AnsiStrAlloc(MAX_LOGSTR_LEN); tmpError:=AnsiStrAlloc(MAX_LOGSTR_LEN); tmpLog:=AnsiStrAlloc(MAX_LOGSTR_LEN);
FErg:=GetInfosN(PAnsiChar(AnsiString('XXXXX')),PAnsiChar(AnsiString('Name')), PAnsiChar(AnsiString('')),PAnsiChar(AnsiString('12354')), PAnsiChar(AnsiString('55')),PAnsiChar(AnsiString('S')),tmpError,tmpLog,tmpTimes,tmpData, false,true, false,false, false, false); |
Jetzt dachte ich mir ich rufe die Funktion folgendermaßen auf:
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12: 13: 14: 15: 16: 17: 18: 19: 20: 21:
| [DllImport("Meine.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern bool GetInfosN(string PW, string Benutzer, string Auftrag, string Variante, string werk, string stueliHerkunft, ref string strError, ref string strLog, ref string strTimes, ref string strResult, bool aPlan, bool stueli, bool matVerw, bool aNetz, bool klassfz, bool NoXML);
private void button16_Click(object sender, EventArgs e) { timer1.Enabled = false; bool ergebnis; const int sMAX_RESSTR_LEN = 6048580; const int sMAX_LOGSTR_LEN = 99005;
var strError = new String('\x00', sMAX_LOGSTR_LEN); var strLog = new String('\x00', sMAX_LOGSTR_LEN); var strTimes = new String('\x00', sMAX_LOGSTR_LEN); var strResult = new String('\x00', sMAX_RESSTR_LEN);
ergebnis = GetInfosN("XXXXX", "Name", "", "12354", "55", "S", ref strError, ref strLog, ref strTimes, ref strResult, false, true, true, false, false, false);
if (ergebnis == true) GroupBox1.Text = strResult; } |
Jedoch ist strResult immer leer, hat jemand einen Tipp was ich anderst im C# Code machen muss, die DLL möchte ich nicht ändern da ich diese noch in X anderen Programmen (mit Delphi) geschrieben verwendet
Die DLL habe ich mit Delphi XE2 compiliert.
_________________ Es gibt keine dummen Fragen nur dumme Antworten!!!
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Fr 23.01.15 16:14
Versuch mal auf C# Seite anstatt "ref string", "StringBuilder" in der Signatur der Methode zu verwenden.
|
|
Bronstein 
      
Beiträge: 578
Erhaltene Danke: 1
WIN XP
Delphi 6 / Delphi 2006 / Delphi XE
|
Verfasst: Fr 23.01.15 16:36
C#-Quelltext 1: 2: 3: 4: 5: 6: 7: 8:
| [DllImport("SAP_STUELI.dll", CharSet = CharSet.Ansi, CallingConvention = CallingConvention.StdCall)] public static extern bool GetInfosN(string PW, string Benutzer, string Auftrag, string Variante, string werk, string stueliHerkunft, ref string strError, ref string strLog, ref string strTimes, StringBuilder strResult, bool aPlan, bool stueli, bool matVerw, bool aNetz, bool klassfz, bool NoXML); StringBuilder strResult = new StringBuilder(sMAX_RESSTR_LEN); ergebnis = GetInfosN("XXXXX", "Name", "", "12354", "55", "S", ref strError, ref strLog, ref strTimes, strResult, false, true, true, false, false, false);
if (ergebnis == false) MessageBox.Show(strResult.ToString()); |
Leider immernoch leer
_________________ Es gibt keine dummen Fragen nur dumme Antworten!!!
|
|
Ralf Jansen
      
Beiträge: 4708
Erhaltene Danke: 991
VS2010 Pro, VS2012 Pro, VS2013 Pro, VS2015 Pro, Delphi 7 Pro
|
Verfasst: Fr 23.01.15 16:54
Dann gibts vielleicht Probleme beim interpretieren des PAnsiChar. Versuch mal den unmanaged Typ per Attribut zu deklarieren.
Etwa so
C#-Quelltext 1:
| blah ... ref string strTimes, [MarshalAs(UnmanagedType.AnsiBStr)] StringBuilder strResult, bool aPlan, ... blah |
Das AnsiBStr auf PAnsiChar mappt ist jetzt aber nur geraten.
|
|
Bronstein 
      
Beiträge: 578
Erhaltene Danke: 1
WIN XP
Delphi 6 / Delphi 2006 / Delphi XE
|
Verfasst: Fr 23.01.15 17:38
Da bekomme ich einen Error:
C#-Quelltext 1:
| ..., [MarshalAs(UnmanagedType.AnsiBStr)] StringBuilder strResult, ... |
"parameter #10" kann nicht gemarshallt werden: Ungültige verwaltete/nicht verwaltete Typenkombination (StringBuilders muss mit LPStr, LPWStr oder LPTStr kombiniert werden)..
Hier bekomme ich wieder nur einen Leerstring zurück:
C#-Quelltext 1: 2: 3: 4:
| StringBuilder strResult = new StringBuilder(sMAX_RESSTR_LEN); ..., [MarshalAs(UnmanagedType.LPStr)] StringBuilder strResult, ... ..., [MarshalAs(UnmanagedType.LPWStr)] StringBuilder strResult, ... ..., [MarshalAs(UnmanagedType.LPTStr)] StringBuilder strResult, ... |
_________________ Es gibt keine dummen Fragen nur dumme Antworten!!!
|
|
Martok
      
Beiträge: 3661
Erhaltene Danke: 604
Win 8.1, Win 10 x64
Pascal: Lazarus Snapshot, Delphi 7,2007; PHP, JS: WebStorm
|
Verfasst: Mo 26.01.15 05:16
Anderswo verwendet man einfach StringBuilder, ohne Einstellung als was die gemarshallt werden sollen. Die Delphiseite dazu sieht so aus.
Ob das so überhaupt stimmt kann ich dir allerdings auch nicht sagen, ich habs nur von C# nach Delphi übersetzt (mit dem C-Header als Spickzettel).
_________________ "The phoenix's price isn't inevitable. It's not part of some deep balance built into the universe. It's just the parts of the game where you haven't figured out yet how to cheat."
|
|
|