调用页面:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Runtime.InteropServices;
using StructModel;namespace AJAXEnabledWebApplication1.CSClass
{
    
    
    public unsafe class DataDll
    {
        [DllImport("DataDLL.dll",CharSet=CharSet.Ansi)]
        public static extern IntPtr LoadAnaMem(int nIndex);
        //[DllImport("DataDLL.dll", CharSet = CharSet.Ansi)]
        //public static extern void GetAnaValue(int nIndex, IntPtr data);
        public static unsafe analogue test()
        {
            analogue sData;//声明一个结构体
            IntPtr ClientInfor = (IntPtr)Marshal.AllocHGlobal(Marshal.SizeOf(typeof(analogue)));//给指针分配结构体大小的内存空间
            ClientInfor = LoadAnaMem(3);//调用Dll控件的方法,返回值为一个任意指针类型            sData = (analogue)Marshal.PtrToStructure(ClientInfor, typeof(analogue));//从非托管程序中读取数据并赋予当前结构体.            return sData;
        }
    }
}C#结构体页面:
using System;
using System.Data;
using System.Configuration;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using System.Runtime.InteropServices;namespace StructModel
{
        
    [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Ansi)]    
    public struct analogue //遥测数据
    {
        public byte A_sta; //站号
        public int A_id; //序号
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
        public byte[] A_name; //名称 原来是Char的
        public int A_address; //物理地址
        public float A_factor; //系数
        public float A_bottom; //底数
        public byte A_clc; //
        public byte A_flag; //越限标志        public float A_up_yj; //越上限预警值
        public float A_up_yj_jc; //解除越上限预警值
        public float A_up_bj; //越上限报警值
        public float A_up_bj_jc; //解除越上限报警值        public float A_down_yj; //越下限预警值
        public float A_down_yj_jc; //解除越下限预警值
        public float A_down_bj; //越下限报警值
        public float A_down_bj_jc; //解除越下限报警值
        public float A_value; //数值
    }  
    
    public class CStructModel
    {
    }
}呈现后台页面:
using System;
using System.Data;
using System.Configuration;
using System.Collections;
using System.Web;
using System.Web.Security;
using System.Web.UI;
using System.Web.UI.WebControls;
using System.Web.UI.WebControls.WebParts;
using System.Web.UI.HtmlControls;
using AJAXEnabledWebApplication1.CSClass;namespace AJAXEnabledWebApplication1
{
    public unsafe  partial class ZedGraphShow : System.Web.UI.Page
    {
        
        
        protected void Page_Load(object sender, EventArgs e)
        {
            //ArrayList alist = new ArrayList();
            //alist.Add(null);
            //Study1.GetAllClientInfo(ref alist);
            Label1.Text=DataDll.test().A_address.ToString();
        }
    }
}
在这句:            sData = (analogue)Marshal.PtrToStructure(ClientInfor, typeof(analogue));//从非托管程序中读取数据并赋予当前结构体.
进行断点调试时,发现sData的全部值为0,如果先对sData赋初值,那么调用后全部值会再变成0..说明调用是成功的,只是没有读到其中的数据...
我想这个问题主要是在C#中怎么与非托管的Dll控件进行交互的问题,最重要的是C#怎么根据一个内存中的地址去读它的数据...
请大家帮帮忙..或者提供相关资料,谢谢

解决方案 »

  1.   

    dll的函数写的有问题,如果能改的话,建议通过Out参数来范围struct的值。如果不能改的话,直接用unsafe去处理,例如:
    [DllImport("DataDLL.dll",CharSet=CharSet.Ansi)]
    public static extern analogue* LoadAnaMem(int nIndex);
      

  2.   


    改了后出现以下 情况:错误 1 无法获取托管类型(“StructModel.analogue”)的地址和大小,或无法声明指向它的指针 E:\My Documents\Visual Studio 2005\Projects\ZedGraph\ZedGraph\AJAXEnabledWebApplication1\CSClass\DataDll.cs 20 AJAXEnabledWebApplication1提示结构体analogue 有错,不能获取analogue 的地址和大小,我应该怎么办呢?
      

  3.   

    改成下面这样试试,我没有那个Dll,所以无法测试是否能读到数据呵呵。。其它的方面都没有问题,,就是那个CS文件的代码改成这样:using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using System.Runtime.InteropServices;
    using StructModel;namespace AJAXEnabledWebApplication1.CSClass
    {
        
        
        public unsafe class DataDll
        {
            [DllImport("DataDLL.dll",CharSet=CharSet.Ansi)]
            public static extern IntPtr LoadAnaMem(int nIndex);
            //[DllImport("DataDLL.dll", CharSet = CharSet.Ansi)]
            //public static extern void GetAnaValue(int nIndex, IntPtr data);
            public static unsafe analogue test()
            {
                analogue sData = new analogue();//声明一个结构体
                IntPtr ClientInfor;//给指针分配结构体大小的内存空间
                ClientInfor = LoadAnaMem(3);//调用Dll控件的方法,返回值为一个任意指针类型            sData = (analogue)Marshal.PtrToStructure(ClientInfor, typeof(analogue));//从非托管程序中读取数据并赋予当前结构体.            return sData;
            }
        }
    }
      

  4.   

          对于不能获取analogue 的地址和大小的问题是因为结构体中包含了数组或字符串,把下面的去掉就行了,或者换成其它的类型。
     [MarshalAs(UnmanagedType.ByValArray, SizeConst = 40)]
            public byte[] A_name;    //名称 原来是Char的