Hallo Zusammen,
ich möchte in Delphi 2007 Methoden in einer WCF abrufen, welche in C#, also .net gehostet wird. Das funktioniert mit basicHttp-Binding auch. Da ich aber Callbacks implementieren muss kommt das nicht in Frage. Duplex-Bindings sind netTcp-Binding und wsDualHttp-Binding. netTcp Binding kann auf Grund fehlender Interoperabilität nicht in Delphi verwendet werden.
WsDualHttp-Binding ist laut MSDN interoperabel. Ich kann in Delphi die wsdl-Datei fehlerfrei kompilieren und das Programm startet dann auch. Wenn man aber den Befehl ausführt kommt die Meldung das an der Adresse ffffffff ein Fehler aufgetreten ist.
Ich habe mal ein Demoprojekt erstellt um das ganze zu testen. Es soll eine Methode aufgerufen werden, welche zwei double als Parameter erhält. Diese Methode addiert beide Variablen und soll das Ergebnis über die Callbackmethode an den Delphi-Client senden.
Die WCF bietet eine Methode an: void Add(double n, double m);
Die Callback-Methode: void Result(double result);
Was mir noch überhaupt nicht klar ist: Wie definiere ich die Callback-Methode? Der Callback-Contract ist mit IDuplexDemoCallback bezeichnet. Diese Bezeichnung findet man in der vom wsdl-Importer erstellten Unit nicht.
Hier der aufrufende Quelltext:
Delphi-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9:
| var ws:IDuplexDemo; param:Add; begin param.n := 2.2; param.m := 2.8;
ws:=GetIDuplexDemo(false); ws.Add(param); end; |
und hier die Unit, die vom Delphi wsdl-Importer erstellt wurde:
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: 39: 40: 41: 42: 43: 44: 45: 46: 47: 48: 49: 50: 51: 52: 53: 54: 55: 56: 57: 58: 59: 60: 61: 62: 63: 64: 65: 66: 67: 68: 69: 70: 71: 72: 73: 74: 75: 76: 77: 78: 79: 80: 81: 82: 83: 84: 85: 86: 87: 88: 89: 90: 91: 92: 93: 94: 95: 96: 97: 98: 99: 100: 101: 102: 103: 104: 105: 106: 107: 108: 109: 110: 111: 112: 113: 114: 115: 116: 117: 118: 119: 120: 121: 122: 123: 124: 125: 126: 127: 128: 129: 130: 131: 132: 133: 134: 135: 136: 137: 138: 139: 140: 141: 142: 143: 144: 145: 146: 147: 148: 149: 150: 151: 152: 153: 154: 155: 156: 157: 158: 159: 160: 161: 162: 163: 164: 165: 166: 167: 168: 169: 170: 171: 172: 173: 174: 175: 176: 177: 178: 179: 180: 181: 182: 183: 184: 185: 186: 187: 188: 189: 190: 191: 192: 193: 194: 195: 196: 197: 198: 199: 200: 201: 202:
|
unit DuplexDemo;
interface
uses InvokeRegistry, SOAPHTTPClient, Types, XSBuiltIns;
const IS_OPTN = $0001; IS_REF = $0080;
type
Add = class; Result = class;
Add = class(TRemotable) private Fn: Double; Fn_Specified: boolean; Fm: Double; Fm_Specified: boolean; procedure Setn(Index: Integer; const ADouble: Double); function n_Specified(Index: Integer): boolean; procedure Setm(Index: Integer; const ADouble: Double); function m_Specified(Index: Integer): boolean; public constructor Create; override; published property n: Double Index (IS_OPTN) read Fn write Setn stored n_Specified; property m: Double Index (IS_OPTN) read Fm write Setm stored m_Specified; end;
Result = class(TRemotable) private Fresult: Double; Fresult_Specified: boolean; procedure Setresult(Index: Integer; const ADouble: Double); function result_Specified(Index: Integer): boolean; public constructor Create; override; published property result: Double Index (IS_OPTN) read Fresult write Setresult stored result_Specified; end;
IDuplexDemo = interface(IInvokable) ['{DEDB3533-FA08-88C8-BB25-8388A7E5AA41}'] procedure Add(const parameters: Add); stdcall; function Result: Result; stdcall; end;
function GetIDuplexDemo(UseWSDL: Boolean=System.False; Addr: string=''; HTTPRIO: THTTPRIO = nil): IDuplexDemo;
implementation uses SysUtils;
function GetIDuplexDemo(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): IDuplexDemo; const defWSDL = 'http://localhost:1235/DuplexDemo'; defURL = 'http://192.168.0.224:1234/DuplexDemo'; defSvc = 'CalculatorService'; defPrt = 'WSDualHttpBinding_IDuplexDemo'; var RIO: THTTPRIO; begin Result := nil; if (Addr = '') then begin if UseWSDL then Addr := defWSDL else Addr := defURL; end; if HTTPRIO = nil then RIO := THTTPRIO.Create(nil) else RIO := HTTPRIO; try Result := (RIO as IDuplexDemo); if UseWSDL then begin RIO.WSDLLocation := Addr; RIO.Service := defSvc; RIO.Port := defPrt; end else RIO.URL := Addr; finally if (Result = nil) and (HTTPRIO = nil) then RIO.Free; end; end;
constructor Add.Create; begin inherited Create; FSerializationOptions := [xoLiteralParam]; end;
procedure Add.Setn(Index: Integer; const ADouble: Double); begin Fn := ADouble; Fn_Specified := True; end;
function Add.n_Specified(Index: Integer): boolean; begin Result := Fn_Specified; end;
procedure Add.Setm(Index: Integer; const ADouble: Double); begin Fm := ADouble; Fm_Specified := True; end;
function Add.m_Specified(Index: Integer): boolean; begin Result := Fm_Specified; end;
constructor Result.Create; begin inherited Create; FSerializationOptions := [xoLiteralParam]; end;
procedure Result.Setresult(Index: Integer; const ADouble: Double); begin Fresult := ADouble; Fresult_Specified := True; end;
function Result.result_Specified(Index: Integer): boolean; begin Result := Fresult_Specified; end;
initialization InvRegistry.RegisterInterface(TypeInfo(IDuplexDemo), 'http://tempuri.org/', 'utf-8'); InvRegistry.RegisterDefaultSOAPAction(TypeInfo(IDuplexDemo), 'http://tempuri.org/IDuplexDemo/%operationName%'); InvRegistry.RegisterInvokeOptions(TypeInfo(IDuplexDemo), ioDocument); InvRegistry.RegisterInvokeOptions(TypeInfo(IDuplexDemo), ioLiteral); InvRegistry.RegisterInvokeOptions(TypeInfo(IDuplexDemo), ioSOAP12); RemClassRegistry.RegisterXSClass(Add, 'http://tempuri.org/', 'Add'); RemClassRegistry.RegisterSerializeOptions(Add, [xoLiteralParam]); RemClassRegistry.RegisterXSClass(Result, 'http://tempuri.org/', 'Result'); RemClassRegistry.RegisterSerializeOptions(Result, [xoLiteralParam]);
end. |
Ich kenne mich in Delphi absolut nicht aus. Ich bitte um Eure mithilfe!
Danke im Voraus!