无法拨号 我用的是 win7 的vs2010对 PInvoke 函数“BuSiNiao!BuSiNiao.RAS::RasGetConnectionStatistics”的调用导致堆栈不对称。原因可能是托管的 PInvoke 签名与非托管的目标签名不匹配。请检查 PInvoke 签名的调用约定和参数与非托管的目标签名是否匹配。请问高手如何解决求赐教

解决方案 »

  1.   

    [DllImport("rasapi32.dll", CharSet = CharSet.Auto)]
            internal static extern uint RasGetConnectionStatistics(
                IntPtr hRasConn,       // handle to the connection
                [In, Out]RasStats lpStatistics  // buffer to receive statistics
                );
    RAS.RasGetConnectionStatistics(lprasConn.hrasconn, stats);
      

  2.   

    为了在4.0下面用,弄了我一个晚上,网上的C#版adsl类好几个方法都有问题,特别是枚举连接名称的方法。在网上找了半天找到这里却没有解决方法,现在差不多解决了,故把解决方法列出来,以方便遇到相同问题的人:
    凡是“对 PInvoke 函数**的调用导致堆栈不对称”都是dll函数的定义问题。        [DllImport("rasapi32.dll", CharSet = CharSet.Auto)]
            internal static extern uint RasGetConnectionStatistics(
                IntPtr hRasConn,       // handle to the connection
                [In, Out]RasStats lpStatistics  // buffer to receive statistics
                );
    中的[in,Out]改为:        [DllImport("rasapi32.dll", CharSet = CharSet.Auto)]
            internal static extern uint RasGetConnectionStatistics(
                IntPtr hRasConn,       // handle to the connection
                ref RasStats lpStatistics  // buffer to receive statistics
                );原因好像是4.0不支持[in,Out]了,3.5支持,所以在3.5下调用是正常的,4.0下报错,但切换框架时vs2010编辑器中不会有这个错误提示。还有“ [In, Out]RasEntryName[] lprasentryname, // buffer to receive”等dll函数定义中的 [In, Out] 都要改为 ref,调用时用 ref lprasentryname[0]            //RasEnumEntries function
                //http://msdn.microsoft.com/en-us/library/windows/desktop/aa377380(v=vs.85).aspx
                uint retval = RAS.RasEnumEntries(null, null, ref names[0], ref lpSize, out lpNames);           // http://msdn.microsoft.com/en-us/library/windows/desktop/bb530704(v=vs.85).aspx
               //返回值为603(ERROR_BUFFER_TOO_SMALL)的话,定义的数组太小,不止一个连接,
                //返回值为632(ERROR_INVALID_SIZE) Incorrect structure size. 结构体错误,C++中数组在内存块中是连续的,C#不一定,所以,需要将C#的数组放到连续的非托管内存中去。
                //所以参考了:
                 //如何通过P/Invoke返回Struct和String Array - magicdlf - 博客园
                 //http://www.cnblogs.com/magicdlf/archive/2009/03/03/PInvoke.html
                //code project上的经典文章
                //http://www.codeproject.com/KB/cs/marshalarrayofstrings.aspx                IntPtr outArray = GenericMarshaller.IntPtrFromStuctArray<RasEntryName>(names);
                    retval = RAS.RasEnumEntries_more(null, null, outArray, ref lpSize, out lpNames);
                    if (retval == 0)
                    {
                        RasEntryName[] names_out = GenericMarshaller.StuctArrayFromIntPtr<RasEntryName>(outArray, lpNames);
                        names = names_out;
                    }