zoukankan      html  css  js  c++  java
  • Delphi 调用C# webservice (转)

    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;

  • 相关阅读:
    树莓派远程连接工具VNC使用教程
    winform开发之UI系列
    设计winform自带动态加载工具按钮和实现热键响应
    winform版弹框操作
    vs2012中将图片放到resource中进行调用
    构建winform控件数据缓存器
    c#跨线程访问控件帮助类
    CSS3过渡
    JavaScript 内置对象 Array 数组
    JavaScript 数组sort方法使用
  • 原文地址:https://www.cnblogs.com/zhangzhifeng/p/3096698.html
Copyright © 2011-2022 走看看