GaryZhu 2009-08-07
大家都知道C# Webservice技术的出现将各种开发技术和语言完全的融合了,下面就这种融合在C#和delphi之间的交互做一次全面的体现,前者是目前最好的开发平台,后者依然是小型c/s系统的最佳选择.
1.使用C#创建一个Webservice服务。
使用vs2005的模板创建C# Webservice非常容易。原文件如下:
[WebService(Namespace = \"http: //localhost/webserver/\")] [WebServiceBinding(ConformsTo = WsiProfiles.BasicProfile1_1)] public class Service : System.Web.Services.WebService { public Service () { //如果使用设计的组件,请取消注释以下行 InitializeComponent(); } #region Component Designer generated code private void InitializeComponent() { } //Web 服务设计器所必需的 private IContainer components = null; protected override void Dispose (bool disposing) { if (disposing && components != null) { components.Dispose(); } base.Dispose(disposing); } #endregion //这个是自动生成的一个webservice函数, 可以不要。 [WebMethod] public string HelloWorld() { return \"Hello World\"; } //这个才是我们自己创建的, [WebMethod] public int addnumber(int a, int b) { return = a + b; } }
2.使用delphi创建一个dll(非com的dll),该dll调用上面的webserivce服务。
使用delphi调用C#的webservice过程也很容易,但是对于新手可能比较麻烦(我就是这么过来的)
第一步:创建一个dll单元:
{$R *.res} function GetNum(a,b:integer): integer stdcall; [Page] var ireturn :Integer; begin ireturn:=GetServiceSoap().addnumber(a,b); //这个GetServiceSoap是什么,看后面... result:=ireturn; end; exports GetNum name ’GetNum’; begin end. //如果是delphi调用该dll必须使用下面的代码。 C#调用则不需要了(C#还是要牛一些,呵呵) initialization coinitialize(nil); finalization counInitializ 第二步:将webserivce的WSDL导入到该dll工程中, 如何导,方法至少有两种,我说简单的一种: file->new->other->WebService->WSDL Importer, (将C#的WSDL输入)然后delphi会自动给你生成了一个pas文件, function GetServiceSoap(UseWSDL: Boolean; Addr: string; HTTPRIO: THTTPRIO): ServiceSoap; const defWSDL = ’http://localhost/webserver/ Service.asmx?WSDL’; defURL= ’http://localhost/webserver/ Service.asmx’; defSvc= ’Service’; defPrt= ’ServiceSoap’; 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 //RIO.HTTPWebNode.UseUTF8InHeader:= True; //在此添加一句,修改编码方案。 Result := (RIO as ServiceSoap); 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; initialization InvRegistry.RegisterInterface (TypeInfo(ServiceSoap), ’ http://localhost/webserver/’, ’ utf-8’); [Page] InvRegistry.RegisterDefaultSOAPAction (TypeInfo(ServiceSoap), ’ http://localhost/webserver/%operationName%’); //对于无法识别传入的参数的问题,需要手工加上这一句>...... InvRegistry.RegisterInvokeOptions(TypeInfo (ServiceSoap), ioDocument); 这段代码基本上你不用关心,但是,有两个地方需要特别注意: 1.RIO.HTTPWebNode.UseUTF8InHeader:=True; 对于中文参数必须加上 2.InvRegistry.RegisterInvokeOptions (TypeInfo(ServiceSoap), ioDocument);
如果传入的参数不能被webservice识别时,多半是因为你没有加上这一句。
3.使用delphi调用上面的dll 就一个函数,没有什么好说的:
procedure TForm1.Button1Click(Sender: TObject); type GetNumTotal=function(a,b:integer):integer;stdcall; var Th:Thandle; Tf:GetNumTotal; Tp:TFarProc; begin Th:=LoadLibrary(’mywebservice.dll’); {装载DLL} if Th〉0 then try Tp:=GetProcAddress(Th,PChar(’GetNum’)); if Tp〈 〉nil then begin Tf:=GetNumTotal(Tp); Edit1.Text:=IntToStr(Tf(1,3)); {调用GetNumTotal函数} end else ShowMessage(’GetNumTotal函数没有找到’); finally FreeLibrary(Th); {释放DLL} end else ShowMessage(’mywebservice.dll没有找到’); end;