张志峰的博客

水滴石川,积少成多。

导航

Delphi 调用C# webservice (转)

Posted on 2013-05-24 13:36  ╰★张志峰★╮  阅读(1320)  评论(0编辑  收藏  举报

webservicedelphic#dllintegerinitialization转自:http://www.cnblogs.com/jdmei520/archive/2009/06/17/1505053.html

Webservice技术的出现将各种开发技术和语言完全的融合了,下面就这种融合在C#和delphi之间的交互做一次全面的体现

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;

4.使用C#调用上面的dll

[DllImport("mywebservice.dll", EntryPoint = "GetNum")]
public static extern int GetNum(int a, int b);
private void button1_Click(object sender, EventArgs e)
{
      int a,b,i;
      a=10;
      b =20;
      i=GetNum(a,b);   //第一次比较慢(webserivce的唯一弊端!!!!)
      textBox1.Text = i.ToString();  
   }

以下个人经验

在delphi调用 .net webservice时,中文传递过去就会变成????

问题原因:是因为传递时没用使用UTF8方式进行传递。

解决方式:在生成的pas文件中,找到Get*Soap的方法,在中间加入橙色字体那部分。就能够传递中文了

RIO := THTTPRIO.Create(nil);
try
     if UseWSDL then
    begin
      RIO.WSDLLocation := Addr;
      RIO.Service := defSvc;
      RIO.Port := defPrt;
      RIO.HTTPWebNode.UseUTF8InHeader := True;//中文
    end else
    begin
      RIO.URL := Addr;
      RIO.HTTPWebNode.UseUTF8InHeader := True;//中文
    end;

    Result := (RIO as VioAccessWebServiceSoap);
finally
    if Result = nil then
      RIO.Free;
end;