精华内容
下载资源
问答
  • SpringMVC 多个对象相同字段参数传递解决方案,在SpringMVC中,有时需要传递多个对象3 在SpringMVC中不支持类似struts2点语法传参法则 使用桥连接,将不同部分专门封装成一个对象(推荐) 优点:减少了...

    SpringMVC 多个对象的相同字段参数传递解决方案,在SpringMVC中,有时需要传递多个对象3

    在SpringMVC中不支持类似struts2的点语法传参法则

     

    使用桥连接,将不同的部分专门封装成一个对象(推荐)

    优点:减少了冲突,减少了工作量

    缺点:冲突字段/总字段趋近于1时显得没必要(不过,这种情况几乎很少出现,除非是继承关系,但继承关系完全可以使用子类来传值,所以这个问题你就当没遇到过)

     

    <form method='post' action='url'>
    用户名 <input type='text' name='u_name'>
    用户id <input type='text' name='u_id'>
    食品名 <input type='text' name='f_name'>
    食品id <input type='text' name='f_id'>
     <input type='text' name='gender'>
     <input type='text' name='age'>
     <input type='text' name='price'>
     <input type='text' name='date'>
    </form>
    
    -----将冲突的字段专门建立一个javaBean
    public String UFBridge{
        
        private String uname;
        private String uid;
        private String fname;
        private String fid;
    }
    --------------------------
    @requestMap(value={'/order/book'})
    public string show(User u,Food f,UFBridge ufb){
    
       u.setName(ufb.getUname());
       f.setName(ufb.getUname());
       
       u.setId(ufb.getUid);
       f.setId(ufb.getFid);
    }

    转载自:https://my.oschina.net/ososchina/blog/344174

    转载于:https://www.cnblogs.com/liuwt365/p/7891805.html

    展开全文
  • C#语言函数参数的传递

    千次阅读 2005-10-27 17:26:00
    C#语言函数参数的传递 就像C语言众多的后世子孙一样,C#的函数参数是非常讲究的。首先,参数必须写在函数名后面的括号里,这里我们有必要称其为形参。参数必须有一个参数名称和明确的类型声明。该参数名称只在函数...
    C#语言函数参数的传递
     
    就像C语言众多的后世子孙一样,C#的函数参数是非常讲究的。首先,参数必须写在函数名后面的括号里,这里我们有必要称其为形参。参数必须有一个参数名称和明确的类型声明。该参数名称只在函数体内部可见。因此在该函数体以外的任何地方使用同样的变量名是不会引起冲突的。每当调用函数的时候,必须将一个实参传递给函数定义中的形参。默认情况下,C#的参数传递是值传递。这种方式的优点和缺点同样明显。另外,在传送引用类型的时候还时不时引起一些小误会。更加使人困惑的是,既然CLR不支持指针类型,那么我们以前在C/C++中的那些关于指针传递的妙用应该如何实现呢?不必发愁,本文将会逐一回答上述这些疑问。首先我们会讨论默认情况下的值传递以及这种方式的优缺点,解释默认情况下传递引用类型时容易产生的误解。然后,我们讨论如何利用ref关键字把一个值类型作为引用类型传递给参数。最后,我们尝试着让一个函数可以返回多个值,在C/C++中我们经常利用指针达到这一目的,这里我们将会利用out关键字重温这种美妙的感觉。
     
    值传递
     
    每当调用一个函数的时候,我们就必须为该函数的每一个形参传递一个实参。默认情况下,采用值传递的机制。也就是说,实参的值会被拷贝到形参里面,这样我们在函数内部得到一个本地变量,该变量的值和传递进来的那个实参的值相等,但是它们存放在不同的存储空间。因此,我们对函数参数所做的一切实际上都是对函数提内本地变量的操作,绝对不会影响到作为实际参数传递过来的那个函数体外的变量。看下面的例子,我就不再多费口舌了。
     
    using System;
     
    namespace CS语言函数参数的传递
    {
         /// <summary>
         /// Class1 的摘要说明。
         /// </summary>
         class Example
         {
             static void Main(string[] args)
             {
                  int argument = 5;
                  Example exp = new Example();
     
                  System.Console.WriteLine(argument);
     
                  exp.fun1(argument);
     
                  System.Console.WriteLine(argument);
             }
     
             public Example()
             {
             }
     
             public void fun1(int parameter)
             {
                  //对parameter的操作实际上是对本地变量的修改
                  //不会影响到函数体外作为实参传递过来的变量
                  parameter += 5;
                  System.Console.WriteLine(parameter);
             }
         }
    }
     
    但是值传递的机制有一个明显的缺点。主要表现在值类型的传递方面。我们对参数的修改会在函数体执行结束之际消失。如果我们希望将这种变化影响到作为实参传递过来的那个函数体以外的变量就必须把值类型作为引用类型传递。后边会具体讨论。值传递机制的另一个缺点,或许你会认为这是一个优点,表现在引用类型的传递方面。按照值传递的机制传递一个引用类型的变量,实际上只是完成了一次浅拷贝。请不要误认为对整个对象进行了深拷贝。函数参数得到的只是实参的handle的值。也就是说,本地的参数实际上只是一个引用类型的handle,和作为实参传递过来的那个变量的handle具有相同的值,指向同一个object(两个handle指向堆上的相同位置)。这样我们在函数内部对参数所做的修改会直接影响到堆上的object。当函数结束之后,本地的参数消失,而对于堆上的object的修改会成为持久的修改而继续保留下来。
     
    把值类型作为引用类型传递
     
    有一些时候,我们不惜望函数对于参数的修改随着函数的结束而消失。作为引用类型,作到这一点其实一点都不难,就像我们上面说的那样。但是,如果是值类型的参数,似乎就有一点麻烦了。从前在C/C++里面可以采取传递指针的方法来达到这个目的。但是CLR已经明确取消了指针。作为补偿,C#为我们提供了ref关键字。ref关键字通知编译器,参数的实参是作为引用类型而非值类型进行传递。下面的这段程序帮助我们说明问题。
     
    using System;
     
    namespace CS语言函数参数的传递
    {
         class Example
         {
             static void Main(string[] args)
             {
                  int argument = 5;
                  Example exp = new Example();
     
                  //首先显示argument
                  System.Console.WriteLine(argument);
                  exp.fun2(ref argument);//传递参数时必须使用ref关键字
                  System.Console.WriteLine(argument);
     
                  System.Console.ReadLine();
             }
     
             public void fun1(int parameter)
             {
                  //对parameter的操作实际上是对本地变量的修改
                  //不会影响到函数体外作为实参传递过来的变量
                  parameter += 5;
                  System.Console.WriteLine(parameter);
             }
     
             public void fun2(ref int parameter)
             {
                  parameter += 5;
                  System.Console.WriteLine(parameter);
             }
         }
    }
     
    函数fun2要求一个int类型的参数,并且伴有关键字ref。在Main()函数内定义了一个整形变量argument,它将会作为实参传递给函数fun2()。在调用该函数之前,首先显示了变量argument,其值等于5。紧接着调用函数fun2(),并且传递argument给参数parameter。这时函数得到的是一个本地的,指向整形变量argument的handle。在函数内部,把parameter加5,然后显示它。这时其值为10。函数返回后再一次显示argument,其值同样为10。
     
    让函数返回多个返回值
     
    有些时候我们可能会希望一个函数可以返回多个返回值。事实上,这是不可能的因为一个函数只能返回一个返回值。但是我们确实办法达到这种效果。最简单的是下面这种方法。
     
    public int fun3(ref int i, int j)
             {
                  i = j;
     
                  return i + j;
             }
     
    我们这样调用这个函数。
     
    int i;
                  int sum = exp.fun3(ref i, 10);
                  System.Console.WriteLine(i);
                  System.Console.WriteLine(sum);
     
    这样在执行过函数fun3()之后,我们实际上得到了i的值和i + j的值。实际上起到了利用一个函数返回两个值的作用。另外有一个关键字也是非常重要的。那就是out关键字。该关键字允许向参数传递一个没有分配空间的引用类型。利用这个关键字同样可以达到返回多个值的目的。
     
    public void fun4(ref int i, out object obj)
             {
                  i+=5;
                  obj = i.ToString();
                  System.Console.WriteLine(i);
                  System.Console.WriteLine(obj);
             }
     
    上面这个方法要求两个参数。第二个参数要求一个object类型的变量。该参数前面有一个out关键字。编译器会认为该参数的实参没有被分配存储空间。Out参数在未被赋值之前不能使用。可以这样调用该函数:
     
    int i = 5;
                  object obj;
                  exp.fun4(ref i, out obj);
                  System.Console.WriteLine(i);
                  System.Console.WriteLine(obj);
     
    输出为4个10。说明我们在调用该函数之后得到了变量i和obj两个变量的值。
    展开全文
  • ASP.NET页面间参数传递一.使用QueryString使用QueryString在页面间传递值是一种非常常见方法,我们在ASP中就常常用到。...在源页面代码中用需要传递的名称和值构造URL地址。2.在源页面代码用...
    ASP.NET页面间参数传递
    一.使用QueryString
    使用QueryString在页面间传递值是一种非常常见的方法,我们在ASP中就常常用到。
    (1)优点和缺点
    优点:
    1.使用简单,对于安全性要求不高时传递数字或是文本值非常有效。
    缺点:
    1.缺乏安全性,由于它的值暴露在浏览器的URL地址中的。
    2.不能传递对象。
    (2)使用方法
    1.在源页面的代码中用需要传递的名称和值构造URL地址。
    2.在源页面的代码用Response.Redirect(URL);重定向到上面的URL地址中。
    3.在目的页面的代码使用Request.QueryString["name"];取出URL地址中传递的值。
    (3)应用举例
    1.源页面*.aspx的代码:
    private void Button1_Click(object sender, System.EventArgs e)
    {
    string urlAddress;
    string Name1;
    string Name2;
    string Name3;
    string Name1Value = "HelloName1";
    int Name2Value = 1234567;
    string Name3Value = "你好名称3";
    urlAddress = "destinationWebForm.aspx?Name1=" + Name1Value + "&" + "Name2=" + Name2Value.ToString() + "&" + "Name3=" +
    Name3Value;
    Response.Redirect(urlAddress);
    }
    2.目的页面destinationWebForm.aspx的代码:
    private void Page_Load(object sender, System.EventArgs e)
    {
    string myName1Value;
    intmyName2Value;
    string myName3Value;
    myName1Value = Request.QueryString["Name1"];
    myName2Value = Convert.ToInt32(Request.QueryString["Name2"]);
    myName3Value = Request.QueryString["Name3"];
    }
    (4)可能出现的问题
    1在处理Resonse.QueryString函数汉字参数传递时,发生不能完整传递参数的具体值的错误,解决有两个方法。
    方法一:需要重新设置Web.config中的encoding和全球化设置。
    1、首行:<?xml version="1.0" encoding="utf-8" ?>
    更改为:
    <?xml version="1.0" encoding="GB2312" ?>
    2、<!--全球化
    此节设置应用程序的全球化设置。
    -->
    <globalization
    requestEncoding="utf-8"
    resp
    />
    更改为:
    <!--全球化
    此节设置应用程序的全球化设置。
    -->
    <globalization
    requestEncoding="GB2312"
    resp
    />
    [1]
    方法二:使用Server.UrlEncode和Server.UrlDecode对汉字或者特殊字符进行编码和解码。
    二、使用Application变量
    使用Application变量是在页面间传递值的第二种方式。
    Application变量在整个应用程序生命周期中都是有效的,类似于使用全局变量一样,所以可以在不同页面中对它进行存取。它和Session
    变量的区别在于,前者是所有的用户共用的全局变量,后者是各个用户独有的全局变量。
    举个例子来解释:
    网站访问的计数器变量一般采用Application变量,多个请求访问时共享这一个变量,均可对它进行操作,该变量可以被整个应用程序的各
    个页面直接使用。
    用户登陆的帐号名一般采用Session变量,多个请求访问时有各自的Session变量,只能对自己的该Session变量进行操作,整个应用程序的
    各个页面直接使用这个变量来获得用户的基本信息。
    (1)优点和缺点
    优点:
    1.使用简单,消耗较少的服务器资源。
    2.不仅能传递简单数据,还能传递对象。
    3.数据量大小是不限制的。
    缺点:
    1.作为全局变量容易被误操作。
    (2)使用方法
    1.在源页面的代码中创建你需要传递的名称和值构造Application变量:Application["Nmae"]="Value(Or Object)";
    2.在目的页面的代码使用Application变量取出传递的值。Result = Application["Nmae"]
    (3)应用举例
    1.源页面 *.aspx的代码:
    private void Button1_Click(object sender, System.EventArgs e)
    {
    string Name1Value = "HelloName1";
    int Name2Value = 1234567;
    Application["Name1"] = Name1Value;
    Application["Name2"] = Name2Value;
    }
    2.目的页面 *.aspx的代码:
    private void Page_Load(object sender, System.EventArgs e)
    {
    string myName1Value;
    intmyName2Value;
    myName1Value = Application["Name1"].ToString();
    myName2Value = (int)Application["Name2"];
    }

    三、使用Session变量
    使用Application变量是在页面间传递值的第三种方式。Session变量和Application变量非常类似,它们的区别也已经在上面关于
    Application变量时提到了。
    (1)优点和缺点
    优点:
    1.使用简单,不仅能传递简单数据类型,还能传递对象。
    2.数据量大小是不限制的。
    缺点:
    1.在Session变量存储大量的数据会消耗较多的服务器资源。

    (2)使用方法
    1.在源页面的代码中创建你需要传递的名称和值构造Session变量:Session["Nmae"]="Value(OrObject)";
    2.在目的页面的代码使用Session变量取出传递的值。Result = Session["Nmae"]
    (3)应用举例
    与Application变量类似,只是将Application替换为Session即可。
    四、使用Cookie对象

    使用Cookie对象是在页面间传递值的第四种方式。Cookie用于在用户浏览器上存储小块的信息,保存用户的相关信息,比如用户访问某网站
    时用户的ID,用户的偏好等,用户下次访问就可以通过检索获得以前的信息。所以Cookie也可以在页面间传递值。Cookie通过HTTP头在浏览器
    和服务器之间来回传递的。Cookie只能包含字符串的值,如果想在Cookie存储整数值,那么需要先转换为字符串的形式。
    可以通过遍历Request对象的Cookie集合可以获得所有的浏览器所有的Cookie。方法如下:
    foreach (string strKey in Request.Cookies)
    {
    lblCookies.Text += strKey + "=" + Request.Cookies[ strKey ].Value;
    }

    (1)优点和缺点
    优点:
    1.使用简单,是保持用户状态的一种非常常用的方法。比如在购物网站中用户跨多个页面表单时可以用它来保持用户状态。
    缺点:
    1.常常被人认为用来收集用户隐私而遭到批评。

    (2)使用方法
    1.在源页面的代码中创建你需要传递的名称和值构造Cookie对象:
    HttpCookie objCookie = new HttpCookie("myCookie","Hello,Cookie!");
    Response.Cookies.Add(cookie);
    2.在目的页面的代码使用Cookie对象取出传递的值:Result = Request.Cookies[ "myCookie" ].Value;
    (3)应用举例
    1.源页面 *.aspx的代码:
    private void Button1_Click(object sender, System.EventArgs e)
    {
    HttpCookie objCookie = new HttpCookie("myCookie","Hello,Cookie!");
    Response.Cookies.Add(objCookie);
    }
    2.目的页面 *.aspx的代码:
    private void Page_Load(object sender, System.EventArgs e)
    {
    string myName1Value;
    myName1Value = Request.Cookies[ "myCookie" ].Value;
    }
    五、使用Server.Transfer

    使用Server.Transfer变量是在页面间传递值的第五种方式。上面的四个方法我们在ASP中常常使用,但是这个方法是在ASP.NET中新出现的
    。Server.Transfer是从当前的ASPX页面转到新的ASPX页面,服务器端执行新页并输出,在新页面中通过Context.Handler来获得前一个页面传递
    的各种数据类型的值、表单数据、QueryString.由于重定向完全在服务器端完成,所以客户端浏览器中的URL地址是不会改变的。
    调用Server.Transfer时,当前的ASPX页面终止执行,执行流程转入另一个ASPX页面,但新的ASPX页面仍使用前一ASPX页面创建的应答流。
    [2]
    在这里比较一下Server.Transfer和在“一”中使用的Response.Redirect的区别。
    (1)Server.Transfer在服务器端完成,所以客户端浏览器中的URL地址是不会改变的;Response.Redirect是客户端完成,向服务器端提出
    新的页面处理请求,所以客户端浏览器中的URL地址是会改变的。
    (2)Server.Transfer在服务器端完成,不需要客户端提出请求,减少了客户端对服务器端提出请求。[2]
    (3)Server.Transfer只能够转跳到本地虚拟目录指定的页面,也就是工程项目中的页面,而Response.Redirect则十分灵活,可以跳转到任何
    URL地址。
    (4)Server.Transfer可以将前一个页面的各种类型的值传到新的页面;Response.Redirect则只能借助URL中带参数或是结合上面四种办法
    把各种类型的值传到新的页面。

    继续我们的Server.Transfer用法。
    (1)优点和缺点
    优点:
    1.直接在服务器端重定向,使用简单方便,减少了客户端对服务器端提出请求。
    2.可以传递各种数据类型的值和控件的值。
    缺点:
    1.客户端浏览器中的URL地址是不改变,会导致在新的页面可能出现一些意想不到的问题。比如如果源页面和目的页面不在同一个虚拟目录
    或其子目录下,那么使用相对路径的图片、超链接都会导致错误的指向。[3]

    (2)使用方法
    1.在源页面的代码中,使用Page类的Server.Transfer跳到另一个页面传递页面数据:
    Server.Transfer("destinationWebForm.aspx","false")。
    2.在目的页面中,使用Context.Handler来接收数据:
    FormerPage formerPage = (FormerPage)Context.Handler;
    然后用formerPage的属性和方法来获取前一个页面的值,或者直接用
    Context.Items["myParameter "]
    来获取前一个页面的值。
    需要注意的是获取这些值必须在新的页面首次加载时,才能正确获取上一页面的各种数据类型或是控件的值。在以后的postback时,就无法
    获取上一页面的各种数据类型或是控件的值了,因为此时得到的当前页面的实例. 所以需要在新页面(destinationWebForm.aspx)的Page_Load
    ()事件中使用if(!IsPostBack)把获取前一个页面的值的代码包含起来,才能获得前一个页面传递的各种数据类型的值、表单数据、
    QueryString。
    (3)应用举例
    1.源页面 FormerPage.aspx的代码:
    public string HelloContextAttribute
    {
    get
    {
    return "Use Attribute: Hello,Context";
    }
    }
    public string HelloContextMethod()
    {
    return "Call Method: Hello,Context!";
    }
    public string TextBoxValue
    {
    get
    {
    return TextBox1.Text;
    }
    }

    private void Button1_Click(object sender, System.EventArgs e)
    {
    string Name1Value = "Hello, Name1!";
    TextBox1.Text ="Hello,TextBox1!";
    ArrayList myList = new ArrayList(3);//创建动态数组
    myList.Add("Hello,Array1! ");//向动态数组中添加新的值
    myList.Add("Hello,Array2!");
    myList.Add("Hello,Array3!");
    //Context可保存任意数据类型,Context字典特定于某个Http请求。
    //对于不同客户端,值是不一样的。
    Context.Items["destinationList"] = myList;//在Context.Items中保存动态数组
    Context.Items.Add("newContext","Hello,NewContext");//在Context.Items中保存一组名称-值的数据
    //Server.Transfer第二参数如果为true,表示本页面的Form和QuerryString的值在新页面继续有效。
    //否则在新页面无法获得TextBox1的值。
    Server.Transfer("destinationWebForm.aspx?Name1="+ Name1Value,true);
    }

    2.目的页面 destinationWebForm.aspx的代码:

    private void Page_Load(object sender, System.EventArgs e)
    {
    if(!IsPostBack)
    {
    try
    {
    string helloContextAttribute;
    string helloContextMethod;
    string textBoxValue;
    string contextItemsValue;
    string queryString;
    ArrayList listResult;
    FormerPage formerPage = (FormerPage)Context.Handler;
    helloContextAttribute = formerPage.HelloContextAttribute;//通过FormerPage中定义的属性来获取值
    helloContextMethod = formerPage.HelloContextMethod();//通过FormerPage中定义的方法来获取值
    textBoxValue = formerPage.TextBoxValue;//通过FormerPage中返回文本控件的值
    //下面的方法多用于用户在控件中输入值后才能获取,但是在程序中给直接TextBox1.Text赋值,那么下面的方法获得
    //的空值,在这种情况下需要使用上面的获取方法
    //textBoxValue = Request.Form["TextBox1"];

    contextItemsValue = Context.Items["newContext"].ToString();//通过FormerPage中Context的Items获取值
    listResult = (ArrayList)Context.Items["destinationList"];//通过FormerPage中Context的Items获取对象,强制转换类型:
    queryString = Request.QueryString["Name1"];//通过FormerPage的URL中的QueryString获取值
    }
    catch
    {
    Response.Write("Error!");
    }
    }
    }

    (转自:http://blog.csdn.net/chaobaojun/archive/2009/04/21/4097316.aspx

    展开全文
  • C#中调用非托管DLL及参数传递

    千次阅读 2011-03-25 16:47:00
    ?????? 微软的.NET框架的优点之一是...这也就是说,你的参数必须被marshal(注:不知道中文名称该叫什么,英文中指的是为了某个目的而组织人或事物,参见这里,此处指的是为了调用非托管函数而进行的参数转换)。<br /

    ?????? 微软的.NET框架的优点之一是它提供了独立于语言的开发平台。你可以在VBC++C#等语言中编写一些类,而在其它语言中使用(源于.NET中使用了CLS),你甚至可以从另一种语言编写的类中继承。但是你要是想调用以前的非托管DLL,那又会怎么样呢?你必须以某种方式将.NET对象转换为结构体、char *、函数指针等类型。这也就是说,你的参数必须被marshal(注:不知道中文名称该叫什么,英文中指的是为了某个目的而组织人或事物,参见这里,此处指的是为了调用非托管函数而进行的参数转换)。

    ?????? C#中使用DLL函数之前,你必须使用DllImport声明要调用的函数:

    public class Win32 {
      [DllImport("User32.Dll")]
      public static extern void SetWindowText(int h, String s);
      // 函数原型为:BOOL SetWindowText(HWND hWnd, LPCTSTR lpString);
    }

    ?????? DllImport告诉编译器被调函数的入口在哪里,并且将该入口绑定到类中你声明的函数。你可以给这个类起任意的名字,我给它命名为Win32。你甚至可以将类放到命名空间中,具体参见图一。要编译Win32API.cs,输入:

    csc /t:library /out:Win32API.dll Win32API.cs

    ?????? 这样你就拥有了Win32API.dll,并且你可以在任意的C#项目中使用它:

    using Win32API;
    int hwnd = // get it...
    String s = "I'm so cute."
    Win32.SetWindowText(hwnd, s);

    ?????? 编译器知道去user32.dll中查找函数SetWindowText,并且在调用前自动将String转换LPTSTR (TCHAR*)。很惊奇是吧!那么.NET是如何做到的呢?每种C#类型有一个默认的marshal类型,String对应LPTSTR。但你若是试着调用GetWindowText会怎么样呢(此处字符串作为out参数,而不是in参数)?它无法正常调用,是因为String是无法修改的,你必须使用StringBuilder

    using System.Text; // for StringBuilder
    public class Win32 {
      [DllImport("user32.dll")]
      public static extern int GetWindowText(int hwnd,
        StringBuilder buf, int nMaxCount);
      // 函数原型:int GetWindowText(HWND hWnd, LPTSTR lpString, int nMaxCount);
    }

    ?????? StringBuilder默认的marshal类型是LPTSTR,此时GetWindowText可以修改你的字符串:

    int hwnd = // get it...
    StringBuilder cb = new StringBuilder(256);
    Win32.GetWindowText(hwnd, sb, sb.Capacity);

    ?????? 如果默认的类型转换无法满足你的要求,比如调用函数GetClassName,它总是将参数转换为类型LPSTR (char *),即便在定义Unicode的情况下使用,CLR仍然会将你传递的参数转换TCHAR类型。不过不用着急,你可以使用MarshalAs覆盖掉默认的类型:

    [DllImport("user32.dll")]
    public static extern int GetClassName(int hwnd,
      [MarshalAs(UnmanagedType.LPStr)] StringBuilder buf,
      int nMaxCount);
      // 函数原型:int GetClassNameA(HWND hWnd, LPTSTR lpClassName, int nMaxCount);

    ?????? 这样当你调用GetClassName时,.NET将字符串作为ANSI字符传递,而不是宽字符。

    ?????? 结构体和回调函数类型的参数又是如何传递的呢?.NET有一种方法可以处理它们。举个简单的例子,GetWindowRect,这个函数获取窗口的屏幕坐标,C++中我们这么处理:

    // in C/C++
    RECT rc;
    HWND hwnd = FindWindow("foo",NULL);
    ::GetWindowRect(hwnd, &rc);

    ???? 你可以使用C#结构体,只需使用另外一种C#属性StructLayout

    [StructLayout(LayoutKind.Sequential)]
    public struct RECT {
      public int left;
      public int top;
      public int right;
      public int bottom;
    }

    ?????? 一旦你定义了上面的结构体,你可以使用下面的函数声明形式 :

    [DllImport("user32.dll")]
    public static extern int 
      GetWindowRect(int hwnd, ref RECT rc);
      // 函数原型:BOOL GetWindowRect(HWND hWnd, LPRECT lpRect);

    ?????? 使用ref标识很重要,以至于CLR(通用语言运行时)将RECT变量作为引用传递到函数中,而不是无意义的栈拷贝。定义了GetWindowRect之后,你就可以采用下面的方式调用

    RECT rc = new RECT();
    int hwnd = // get it ...
    Win32.GetWindowRect(hwnd, ref rc);

    ?????? 注意你同样需要像声明中的那样使用ref关键字。C#结构体默认的marshal类型是LPStruct,因此没有必要使用MarshalAs。但如果你使用了类RECT而不是结构体RECT,那么你必须使用如下的声明形式:

    // if RECT is a class, not struct
    [DllImport("user32.dll")]
    public static extern int 
      GetWindowRect(int hwnd, 
        [MarshalAs(UnmanagedType.LPStruct)] RECT rc);

    ?????? C#C++一样,一件事情有很多中实现方式。System.Drawing中已经有Rectangle结构体,用来处理矩形,那有为什么要重新发明轮子呢?

    [DllImport("user32.dll")]
    public static extern int GetWindowRect(int hwnd, ref Rectangle rc);

    ?????? 最后,又是怎样从C#中传递回调函数到非托管代码中的呢?你所要做的就是委托(delegate)。

    delegate bool EnumWindowsCB(int hwnd, int lparam);

    ?????? 一旦你声明了你的回调函数,那么你需要调用的函数声明为:

    [DllImport("user32")]
    public static extern int 
      EnumWindows(EnumWindowsCB cb, int lparam);
      // 函数原型:BOOL EnumWindows(WNDENUMPROC lpEnumFunc, LPARAM lParam);

    ?????? 由于上面的委托仅仅是声明了委托类型,你需要在你的类中提供实际的回调函数代码。

    // in your class
    public static bool MyEWP(int hwnd, int lparam) {
      // do something
      return true;
    }

    ?????? 然后传递给相应的委托变量:

    EnumWindowsCB cb = new EnumWindowsCB(MyEWP);
    Win32.EnumWindows(cb, 0);

    ?????? 你可能注意到参数lparam。在C语言中,如果你传递参数LPARAMEnumWindowsWindows将它作为参数调用你的回调函数。通常lparam是包含了你要做的事情的上下文结构体或类指针,记住,在.NET中没有指针的概念!那该怎么做呢?上面的例子中,你可以申明lparamIntPtr类型,并且使用GCHandle来封装它:

    // lparam is IntPtr now
    delegate bool EnumWindowsCB(int hwnd,     IntPtr lparam);
    // wrap object in GCHandle
    MyClass obj = new MyClass();
    GCHandle gch = GCHandle.Alloc(obj);
    EnumWindowsCB cb = new EnumWindowsCB(MyEWP);
       Win32.EnumWindows(cb, (IntPtr)gch);
       gch.Free();

    ?????? 不要忘了使用完之后手动释放它!有时,你需要按照以前那种方式在C#中释放内存。可以使用GCHandle.Target的方式在你的回调函数中使用指针

    public static bool MyEWP(int hwnd, IntPtr param) {
      GCHandle gch = (GCHandle)param;
      MyClass c = (MyClass)gch.Target;
      // ... use it
      return true;
    }

    ?????????? 图2是将EnumWindows封装到数组中的类。你只需要按如下的方式使用即可,而不要纠结于委托和回调中。

    WindowArray wins = new WindowArray();
    foreach (int hwnd in wins) {
     // do something
    }

     

    展开全文
  • 微软的.NET框架的优点之一是它提供了独立于语言的开发平台。你可以在VB、C++、C#等语言中编写一些类,而在其它语言中使用(源于.NET中使用了CLS),你甚至可以从另一种语言编写的类中继承。但是你要是想调用以前的非...
  • 一.使用QueryString 使用QueryString在页面间传递值是一种非常常见方法,我们在ASP中就常常用到。 (1)优点和缺点 优点: 1.使用简单,对于安全性...1.在源页面代码中用需要传递的名称和值构造URL地址。 2.在
  • ASP.NET页面间参数传递一.使用QueryString 使用QueryString在页面间传递值是一种非常常见方法,我们在ASP中就常常用到。 (1)优点和缺点 优点: 1....在源页面代码中用需要传递的名称和值构造URL地址。 ...
  • chapter24委托的优点

    2018-06-10 23:31:21
    委托的优点:1:在算法不变的情况下,优化改进方法的执行效率。...原理(把委托作为参数进行传递)源代码:/*** * * 研究委托的优点 * 举例: * 求1-1000之间的素数 * * */using System;using Sy...
  • 参数名称=参数值")方法,也可以用超链接:,页面跳转后,在目标页面中可用Ruquest["参数名称"]来接收参数。使用QuerySting 方法的优点是实现简单, 不使用服务器资源;缺点是传递的值会显示在浏览器的地址栏上,有...
  • 存储过程的优点和缺点

    千次阅读 2016-03-30 21:16:23
    存储过程位于服务器上,调用时候只需要传递存储过程的名称以及参数就可以了,因此降低了网络传输数据量。 ③安全性。参数存储过程可以防止SQL注入式攻击,而且可以将Grant、Deny以及Revoke权限应用于存储...
  • 使用存储过程的优点

    2015-05-13 08:27:00
    次。 3.提高安全性能:参数存储过程可以防止SQL注入式攻击。...4.减少网络流量:存储过程位于服务器上,调用时候只需要传递存储过程的名称以及参数就可以了,因此降低了网络传输数据量。  
  • mybatis中接口参数使用map类型好处

    千次阅读 2016-10-21 13:22:45
    1.不用指定每个参数的名称. 2.可以传递任意数量和任意类型的参数,而不用对每个参数进行命名和申明,非常利于扩展,在需要时不用额外动Java代码在xml中可以更灵活的获取参数,不用受前端参数变化的影响
  • 关于SSH的优点

    千次阅读 2010-07-04 22:27:00
    使用struts框架好处之一就是所有action类继承一个基类,将访问控制在基类中处理.2.所有action类都继承自...将userid,resource,operation作为参数传递到权限验证接口进行验证.参考strutsdispatchactio
  • 2.减少网络流量 存储过程位于服务器上,调用时候只须传递存储过程的名称以及参数,不用每次访问都传递很长sql 语句3.安全性 减少sql 注入式攻击----------------------------------------...
  • 1.使用Querystring方法 QueryString也叫查询字符串,这种方法将要传递的数据附加在网页地址(URL)后面进行传递。如页面A.aspx跳转到页面B.aspx,可以用Request....使用QuerySting方法的优点是实现简单,不...
  • 存储过程是事先经过编译并存储在数据库中一段SQL语句集合,调用...2、减少网络流量:存储过程位于服务器上,调用时候只需要传递存储过程的名称以及参数就可以了,因此降低了网络传输数据量。 3、安全性:参...
  • 关键字参数 def 函数名(形参名 = 默认值,形参名...优点:由于实参和形参传递是按照位置一一对应关系,当参数太多时容易出现参数传错位置情况 引入关键字参数后,在设置实参时可以指定形参的名称,避免参数传递...
  • 重复使用。存储过程可以重复使用,从而可以...存储过程位于服务器上,调用时候只需要传递存储过程的名称以及参数就可以了,因此降低了网络传输数据量。(4)安全性。参数存储过程可以防止SQL注入式攻击,而...
  • js 获得实例名称

    2014-09-12 11:56:33
    window.myobj=new TestClass(); 在TestClass()中使用下述方法获取实例名。 for(var a in window){ if(window[a]==this){ ... 该方法优点:不用传递参数自动获取,但必须要加为window属性,...
  • C++中给一个函数传递参数的三种方法! 文章目录1. 传递对象本身1.1. 代码对比2. 传递指向对象的指针2.1. 代码对比3. 传递对象的引用(推荐)3.1. 引用的规则3.2. 代码对比4. 123对比总结 C++之所以扩充引用类型,...
  • Scala学习

    2017-06-17 10:39:00
    名称传递参数的方式 使用“按名称传递参数”方式的优点是:1.减少不必要的计算;2.减少异常 在代码中,如果定义函数的时候,传入参数不是传入的值,而是传入的参数名称(如代码中使用t: => Long而不是t...
  • 方法使用

    2020-12-01 10:38:35
    什么是方法:方法就是指一段...返回值类型跟传递的参数类型都是Java中数据类型(基本数据类型、引用数据类型)方法中可以进行返回数据处理(用return来描述)。注意return返回数据类型要与方法数据类型相同,
  • 1.1 使用Querystring 方法  QueryString 也叫查询字符串, 这种方法将要传递的...参数名称=参数值")方法,也可以用超链接:,页面跳转后,在目标页面中可用Ruquest["参数名称"]来接收参数。使用QuerySting 方法的优点
  • mysql存储过程学习

    2019-09-30 20:23:56
    存储过程介绍 存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能SQL 语句集,存储在数据库中,经过第一次...存储过程位于服务器上,调用时候只需要传递存储过程的名称以及参数就可以...
  • 存储过程介绍存储过程(Stored Procedure)是在大型数据库系统中,一组为了完成特定功能...存储过程位于服务器上,调用时候只需要传递存储过程的名称以及参数就可以了,调用一个行数不多存储过程与直接调用SQL...
  • Rust闭包

    2020-09-07 10:51:27
    闭包有一个很通俗的名称:匿名函数,它有着如下优点: 创建闭包不用为函数取名,方便快捷 闭包可以捕获调用者作用域中值 闭包可以被保存进变量或作为参数传递给其他函数 创建闭包 Rust创建闭包语法很简单:|...

空空如也

空空如也

1 2 3 4 5 ... 10
收藏数 191
精华内容 76
关键字:

名称传递参数的优点