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;