C++ DLL原型  结构体定义
const int MAX_QUOTA_STATUS_LEN = 2;
const int MAX_DATE_LEN = 9;
const int MAX_EXCHCODE_LEN = 6;
const int MAX_VARI_LEN = 32;typedef struct ksftquota_pubdata_item_tag
{
int contract_id;
int upd_serial;  
int upd_date;  
int pre_upd_date;  
int pre_upd_serial;  
char sys_recv_time[MAX_DATE_LEN];    char exchCode[MAX_EXCHCODE_LEN];  
char varity_code[MAX_VARI_LEN];  
char deliv_date[MAX_DATE_LEN];  
char chgStatus[MAX_QUOTA_STATUS_LEN];    
double openPrice;  
double lastPrice;  
double highestPrice;  
double lowestPrice;  
int doneVolume;  
double chgPrice;  
double upperLimitPrice;  
double lowerLimitPrice;  
double hisHighestPrice;  
double hisLowestPrice;  
int openInterest;  
double preSettlePrice;  
double preClosePrice;  
double settlePrice;  
double turnover;  
 
int preOpenInterest;  
double closePrice;  
double preDelta;  
double currDelta;  


double bidPrice1;  
int bidVolume1;  
double bidPrice2;  
int bidVolume2;  
double bidPrice3;
int bidVolume3;  
double bidPrice4;  
int bidVolume4;  
double bidPrice5;  
int bidVolume5;   double askPrice1;  
int askVolume1;  
double askPrice2;  
int askVolume2;

double askPrice3;  
int askVolume3;  
double askPrice4;  
int askVolume4;  
double askPrice5;  
int askVolume5;  
}KSFT_QUOTA_PUBDATA_ITEM;
------------------------------------------
函数定义
KSFTQTPUB_API int WINAPI KSFTHQPUB_GetQuota(unsigned char* dataBuf, int bufSize, int timeOut, char* errorMsg);
///////////////////////////////////////////////////////////////
我在C#中定义的 
    public const int MAX_QUOTA_STATUS_LEN = 2;
     public const int MAX_DATE_LEN = 9;
     public const int MAX_EXCHCODE_LEN = 6;
     public const int MAX_VARI_LEN = 32;
[StructLayout(LayoutKind.Sequential)]
 public struct KSFT_QUOTA_PUBDATA_ITEM 
{
int contract_id;
  int upd_serial;  
int upd_date;  
int pre_upd_date;  
int pre_upd_serial;  
    [MarshalAs(UnmanagedType.LPStr, SizeConst = MAX_DATE_LEN)]
    public string sys_recv_time;   
    [MarshalAs(UnmanagedType.LPStr, SizeConst = MAX_EXCHCODE_LEN)]
    public string exchCode;  
    [MarshalAs(UnmanagedType.LPStr, SizeConst = MAX_VARI_LEN)]
    public string varity_code;  
    [MarshalAs(UnmanagedType.LPStr, SizeConst = MAX_DATE_LEN)]
    public string deliv_date;  
    [MarshalAs(UnmanagedType.LPStr, SizeConst = MAX_QUOTA_STATUS_LEN)]
    public string chgStatus;    
double openPrice;  
double lastPrice;  
double highestPrice;  
double lowestPrice;  
int     doneVolume;  
double chgPrice;  
double upperLimitPrice;  
double lowerLimitPrice;  
double hisHighestPrice;  
double hisLowestPrice;  
int    openInterest;  
double preSettlePrice;  
double preClosePrice;   
double settlePrice;  
double turnover;  

int preOpenInterest;   
double closePrice;  
double preDelta;  
double currDelta;  


double bidPrice1;  
int bidVolume1;  
double bidPrice2;  
int bidVolume2;
double bidPrice3;
int bidVolume3;
double bidPrice4;
int bidVolume4;
double bidPrice5;
int bidVolume5; double askPrice1;
int askVolume1;
double askPrice2;
int askVolume2;
double askPrice3;
int askVolume3;
double askPrice4;
int askVolume4;
double askPrice5;
int askVolume5;
}
[DllImport("KsFtQtPub.dll", EntryPoint = "KSFTHQPUB_GetQuota",CharSet =CharSet.Auto )]
public static extern int KSFTHQPUB_GetQuota(ref KSFT_QUOTA_PUBDATA_ITEM[] databuf, int   bufsize, int timeOut,  StringBuilder  errorMsg);  
调用如下:
  public void GetInfo()
        {
            while (procRtn)
            {
                KSFT_QUOTA_PUBDATA_ITEM[] datasize = new KSFT_QUOTA_PUBDATA_ITEM[50];
                KSFT_QUOTA_PUBDATA_ITEM itemsize = new KSFT_QUOTA_PUBDATA_ITEM();
                StringBuilder errMsg = new StringBuilder(1024);
                int quotaCount = KSFTHQPUB_GetQuota(ref datasize, Marshal.SizeOf(itemsize) * 50, 2000, errMsg);
                if (quotaCount < 0)
                {
                    lbstate.Text = "接收发生错误了";
                }
                else if (quotaCount > 0)
                {
                    lbstate.Text = "正在获得数据";
                    lbErrMsg.Text = quotaCount.ToString();
                    //for (int i = 0; i < datasize.Length - 1; i++)
                    //{
                    //    for (int j = 0; j < datasize[i].exchCode.Length - 1; j++)
                    //    {
                    //        MessageBox.Show(datasize[i].exchCode[j].ToString());
                    //    }
                    //}
                    //bindDl(datasize);
                    //this.Invoke(new BindDl(bindDl), new object[] { datasize });
                }
                else
                    lbstate.Text = "没有获得数据";            }
        }
错误信息: 运行库遇到了错误。此错误的地址为 0x79e71bd7,在线程 0xe58 上。错误代码为 0xc0000005。此错误可能是 CLR 中的 bug,或者是用户代码的不安全部分或不可验证部分中的 bug。此 bug 的常见来源包括用户对 COM-interop 或 PInvoke 的封送处理错误,这些错误可能会损坏堆栈。
也试过用IntPtr来代替指针:
public static extern int KSFTHQPUB_GetQuota(IntPtr databuf, int bufsize, int timeOut, StringBuilder errorMsg);       
      
  public  void GetInfo()
        {
            try
            {
                while (procRtn)
                {                    KSFT_QUOTA_PUBDATA_ITEM[] struc_Data = new KSFT_QUOTA_PUBDATA_ITEM[50];
                    int size = Marshal.SizeOf(struc_Data[0]) * 50;
                    StringBuilder errMsg = new StringBuilder(1024);
                    IntPtr OutAry = IntPtr.Zero;
                    int quotaCount = 0;
                    quotaCount = KSFTHQPUB_GetQuota(OutAry, size, 2000, errMsg);
                    IntPtr current = OutAry;
                    if (quotaCount < 0)
                    {
                        lbstate.Text = "接收发生错误了";
                    }
                    else if (quotaCount > 0)
                    {
                        lbstate.Text = "正在获得数据";
                        lbErrMsg.Text = quotaCount.ToString();
                        for (int i = 0; i < quotaCount; i++)
                        {
                            struc_Data[i] = new KSFT_QUOTA_PUBDATA_ITEM();
                            Marshal.PtrToStructure(current, struc_Data[i]);
                            for (int k = 0;k < struc_Data.Length  - 1; i++)
                            {
                                for (int j = 0; j < struc_Data[i].exchCode.Length - 1; j++)
                                {
                                    MessageBox.Show(struc_Data[i].exchCode[j].ToString());
                                }
                            }
                            Marshal.DestroyStructure(current, typeof(KSFT_QUOTA_PUBDATA_ITEM));//毁坏结构
                            //current = IntPtr.op_explicit(current.ToInt32() + Marshal.SizeOf(struc_Data[i]));
                            current = (IntPtr)(current.ToInt32() + Marshal.SizeOf(struc_Data[i])); //移动指针
                        }
                        Marshal.FreeCoTaskMem(OutAry);//释放内存                        //bindDl(datasize);
                        //this.Invoke(new BindDl(bindDl), new object[] { datasize });
                    }
                    else { lbstate.Text = "没有获得数据"; }
                    //                 }
            }
            catch (Exception e)
            {
                MessageBox.Show(e.ToString());
            }
        }
错误信息: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。

解决方案 »

  1.   

    char exchCode[MAX_EXCHCODE_LEN]; 你用stringbuilder试试。
      

  2.   

    可以先用判断一下结构在两种语言下大小是不是一样的:
    c++里用sizeof()函数
    C#里用Marshal.SizeOf()方法如果不一样,再逐条分析是那个字段出的问题。ps:也需要保证两边的结构对齐方式一致
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
      

  3.   

    我把改成了StringBuilder
    在这句出错了 int size = Marshal.SizeOf(struc_Data[0]) * 50;
     类型“AutoTransaction.FrmMain+KSFT_QUOTA_PUBDATA_ITEM”不能作为非托管结构进行封送处理;无法计算有意义的大小或偏移量。
      

  4.   

    先这样测试:
    [StructLayout(LayoutKind.Sequential)]
    public struct KSFT_QUOTA_PUBDATA_ITEM
    {
        int contract_id;
        int upd_serial;
        int upd_date;
        int pre_upd_date;
        int pre_upd_serial;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DATE_LEN)]
        public byte[] sys_recv_time;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_EXCHCODE_LEN)]
        public byte[] exchCode;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_VARI_LEN)]
        public byte[] varity_code;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DATE_LEN)]
        public byte[] deliv_date;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_QUOTA_STATUS_LEN)]
        public byte[] chgStatus;
        double openPrice;
        double lastPrice;
        double highestPrice;
        double lowestPrice;
        int doneVolume;
        double chgPrice;
        double upperLimitPrice;
        double lowerLimitPrice;
        double hisHighestPrice;
        double hisLowestPrice;
        int openInterest;
        double preSettlePrice;
        double preClosePrice;
        double settlePrice;
        double turnover;    int preOpenInterest;
        double closePrice;
        double preDelta;
        double currDelta;
        double bidPrice1;
        int bidVolume1;
        double bidPrice2;
        int bidVolume2;
        double bidPrice3;
        int bidVolume3;
        double bidPrice4;
        int bidVolume4;
        double bidPrice5;
        int bidVolume5;    double askPrice1;
        int askVolume1;
        double askPrice2;
        int askVolume2;
        double askPrice3;
        int askVolume3;
        double askPrice4;
        int askVolume4;
        double askPrice5;
        int askVolume5;

    如果不成功再这样:
    [StructLayout(LayoutKind.Sequential, Pack = 1)]
    public struct KSFT_QUOTA_PUBDATA_ITEM
    {
        int contract_id;
        int upd_serial;
        int upd_date;
        int pre_upd_date;
        int pre_upd_serial;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DATE_LEN)]
        public byte[] sys_recv_time;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_EXCHCODE_LEN)]
        public byte[] exchCode;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_VARI_LEN)]
        public byte[] varity_code;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DATE_LEN)]
        public byte[] deliv_date;
        [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_QUOTA_STATUS_LEN)]
        public byte[] chgStatus;
        double openPrice;
        double lastPrice;
        double highestPrice;
        double lowestPrice;
        int doneVolume;
        double chgPrice;
        double upperLimitPrice;
        double lowerLimitPrice;
        double hisHighestPrice;
        double hisLowestPrice;
        int openInterest;
        double preSettlePrice;
        double preClosePrice;
        double settlePrice;
        double turnover;    int preOpenInterest;
        double closePrice;
        double preDelta;
        double currDelta;
        double bidPrice1;
        int bidVolume1;
        double bidPrice2;
        int bidVolume2;
        double bidPrice3;
        int bidVolume3;
        double bidPrice4;
        int bidVolume4;
        double bidPrice5;
        int bidVolume5;    double askPrice1;
        int askVolume1;
        double askPrice2;
        int askVolume2;
        double askPrice3;
        int askVolume3;
        double askPrice4;
        int askVolume4;
        double askPrice5;
        int askVolume5;
    }
      

  5.   

    加上这个[StructLayout(LayoutKind.Sequential, Pack = 1)]
    c++里用sizeof()函数 
    C#里用Marshal.SizeOf()方法
    获得大小是一样的
      

  6.   

    我也试了..
    在这句出错了 int size = Marshal.SizeOf(struc_Data[0]) * 50; 
     类型“AutoTransaction.FrmMain+KSFT_QUOTA_PUBDATA_ITEM”不能作为非托管结构进行封送处理;无法计算有意义的大小或偏移量。
      

  7.   

    int size = 2000;//Marshal.SizeOf(struc_Data[0]) * 50;
    我这句估计了个.没有报错.我去内网测试下来
      

  8.   

    测试结果.还是报这样的错.
    quotaCount = KSFTHQPUB_GetQuota(OutAry, size, 2000, errMsg);
    尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
      

  9.   

    如果出错你就把你的代码帖出来,光说现象没用。估计是你没有认真看我的代码,仔细看区别:你的
    [MarshalAs(UnmanagedType.LPStr, SizeConst = MAX_DATE_LEN)]
    public string sys_recv_time;我的
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DATE_LEN)]
    public byte[] sys_recv_time;
      

  10.   

    这个是我刚刚测试的代码
    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Collections;
    using System.Data;
    using System.Drawing;
    using System.Text;
    using System.Windows.Forms;
    using System.Runtime.InteropServices;
    namespace AutoTransaction
    {    public partial class FrmMain : Form
        {
            public FrmMain()
            {
                InitializeComponent();
            }
            bool procRtn = false;
            
            private void BtnStart_Click(object sender, EventArgs e)
             {                lbOperation.Text = "开始交易";
                     System.Threading.Thread th = new System.Threading.Thread(GetInfo);
                    th.Start();
        
            }
            [DllImport("KsFtQtPub.dll", EntryPoint = "KSFTHQPUB_Start")]
            public static extern bool KSFTHQPUB_Start(int udpPort, StringBuilder errorMsg);
            [DllImport("KsFtQtPub.dll", EntryPoint = "KSFTHQPUB_Stop")]
            public static extern bool KSFTHQPUB_Stop();
            [DllImport("KsFtQtPub.dll", EntryPoint = "KSFTHQPUB_GetQuota",CharSet =CharSet.Auto )]
            public static extern int KSFTHQPUB_GetQuota( IntPtr databuf, int bufsize, int timeOut, StringBuilder errorMsg);   
          //public static extern int KSFTHQPUB_GetQuota(ref KSFT_QUOTA_PUBDATA_ITEM[] databuf, int   bufsize, int timeOut,  StringBuilder  errorMsg);     
            /// 结构体定义
         public const int MAX_QUOTA_STATUS_LEN = 2;
         public const int MAX_DATE_LEN = 9;
         public const int MAX_EXCHCODE_LEN = 6;
         public const int MAX_VARI_LEN = 32;
    [StructLayout(LayoutKind.Sequential,Pack =1)]
     public struct KSFT_QUOTA_PUBDATA_ITEM 
    {
    int contract_id; //由交易品种和交割期算出来的id,对应:id号;
    int upd_serial; //行情更新序号,对应:序号
    int upd_date; //行情日期,格式:YYYYMMDD
    int pre_upd_date; //行情上次更新日期(保留)
    int pre_upd_serial; //上次更新时的序号(保留)
        [MarshalAs(UnmanagedType.LPStr, SizeConst = MAX_DATE_LEN)]
        public StringBuilder sys_recv_time; //行情服务器收到行情的时间,行情服务器唯一维护,格式:HH:MM:SS    [MarshalAs(UnmanagedType.ByValArray , SizeConst = MAX_EXCHCODE_LEN)]
        public byte [] exchCode; //交易所代码
         [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_VARI_LEN)]
        public byte[] varity_code; //品种代码
         [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DATE_LEN)]
        public byte[] deliv_date; //交割期
         [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_QUOTA_STATUS_LEN)]
        public byte[] chgStatus; //对应:状态
    //1-2bit表示:买入;3-4bit表示:卖出;
    //5-6bit表示:最新;7-8bit不用;
    //00->新行情    01->低于以前的行情
    //11->高于以前的行情    00->与以前相平
        //char sys_recv_time[MAX_DATE_LEN]; //行情服务器收到行情的时间,行情服务器唯一维护,格式:HH:MM:SS    //char exchCode[MAX_EXCHCODE_LEN]; //交易所代码
        //char varity_code[MAX_VARI_LEN]; //品种代码
        //char deliv_date[MAX_DATE_LEN]; //交割期
        //char chgStatus[MAX_QUOTA_STATUS_LEN]; //对应:状态
    double openPrice; //开盘价
    double lastPrice; //最新价
    double highestPrice; //最高价
    double lowestPrice; //最低价
    int     doneVolume; //成交量
    double chgPrice; //涨跌
    double upperLimitPrice; //涨停板
    double lowerLimitPrice; //跌停板
    double hisHighestPrice; //历史最高价
    double hisLowestPrice; //历史最低价
    int    openInterest; //净持仓
    double preSettlePrice; //昨日结算
    double preClosePrice; //昨日收盘
    double settlePrice; //今日结算
    double turnover; //成交金额
    //20061208新增,qbin
    int preOpenInterest; //昨日持仓量
    double closePrice; //今日收盘
    double preDelta; //昨虚实度
    double currDelta; //今虚实度


    double bidPrice1; //买入价1
    int bidVolume1; //买入量1
    double bidPrice2; //买入价2
    int bidVolume2; //买入量2
    double bidPrice3; //买入价3
    int bidVolume3; //买入量3
    double bidPrice4; //买入价4
    int bidVolume4; //买入量4
    double bidPrice5; //买入价5
    int bidVolume5; //买入量5 double askPrice1; //卖出价1
    int askVolume1; //卖出量1
    double askPrice2; //卖出价2
    int askVolume2; //卖出量2
    double askPrice3; //卖出价3
    int askVolume3; //卖出量3
    double askPrice4; //卖出价4
    int askVolume4; //卖出量4
    double askPrice5; //卖出价5
    int askVolume5; //卖出量5
    }
            private void BtnStop_Click(object sender, EventArgs e)
            {
                lbOperation.Text = "停止交易";
                lbstate.Text = "未开始获得数据";
                System.Threading.Thread stop_td = new System.Threading.Thread(Stop);
                stop_td.Start();
            }        private void FrmMain_Load(object sender, EventArgs e)
            {
                StringBuilder Msg = new StringBuilder(1024);
                procRtn = KSFTHQPUB_Start(20518, Msg);
                lbErrMsg.Text = Msg.ToString();
            }
            public void Stop()
            {
                bool c = KSFTHQPUB_Stop();
                procRtn = false;
                if (c)
                {
                    this.lbErrMsg .Text = "停止获得数据";
                    MessageBox.Show("已停止接收行情!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else
                {
                    MessageBox.Show("停止失败", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }        }
              public void GetInfo()
            {
                //try
                //{
                while (procRtn)
                {                KSFT_QUOTA_PUBDATA_ITEM[] struc_Data = new KSFT_QUOTA_PUBDATA_ITEM[50];
                    int size = 2000;//Marshal.SizeOf(struc_Data[0]) * 50;
                    StringBuilder errMsg = new StringBuilder(1024);
                    IntPtr OutAry = IntPtr.Zero;
                    int quotaCount = 0;
                    quotaCount = KSFTHQPUB_GetQuota(OutAry, size, 2000, errMsg);
                    IntPtr current = OutAry;
                    if (quotaCount < 0)
                    {
                        lbstate.Text = "接收发生错误了";
                    }
                    else if (quotaCount > 0)
                    {
                        lbstate.Text = "正在获得数据";
                        lbErrMsg.Text = quotaCount.ToString();
                        for (int i = 0; i < quotaCount; i++)
                        {
                            struc_Data[i] = new KSFT_QUOTA_PUBDATA_ITEM();
                            Marshal.PtrToStructure(current, struc_Data[i]);
                            //for (int k = 0; k < struc_Data.Length - 1; i++)
                            //{
                            //    for (int j = 0; j < struc_Data[i].exchCode.Length - 1; j++)
                            //    {
                            //        MessageBox.Show(struc_Data[i].exchCode[j].ToString());
                            //    }
                            //}
                            Marshal.DestroyStructure(current, typeof(KSFT_QUOTA_PUBDATA_ITEM));//毁坏结构
                            //current = IntPtr.op_explicit(current.ToInt32() + Marshal.SizeOf(struc_Data[i]));
                            current = (IntPtr)(current.ToInt32() + Marshal.SizeOf(struc_Data[i])); //移动指针
                        }
                        Marshal.FreeCoTaskMem(OutAry);//释放内存                    //bindDl(datasize);
                        //this.Invoke(new BindDl(bindDl), new object[] { datasize });
                    }
                    else { lbstate.Text = "没有获得数据"; }
                    //             }
            }
            //catch (Exception e)
            //{
            //    MessageBox.Show(e.ToString());
            //}
            //}
            
            
            
        }
      

  11.   

    [MarshalAs(UnmanagedType.LPStr, SizeConst = MAX_DATE_LEN)]
        public StringBuilder sys_recv_time; //行情服务器收到行情的时间,行情服务器唯一维护,格式:HH:MM:SS 
    啥也不说了。
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DATE_LEN)]
    public byte[] sys_recv_time;
      

  12.   

    如何将byte[]转换为字符串,参考:Encoding.Default.GetString()方法
      

  13.   

    尝试读取或写入受保护的内存。这通常指示其他内存已损坏。[StructLayout(LayoutKind.Sequential,Pack =1)]
     public struct KSFT_QUOTA_PUBDATA_ITEM 
    {
    int contract_id;  
    int upd_serial;  
    int upd_date;  
    int pre_upd_date;  
    int pre_upd_serial;
         [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DATE_LEN)]
         public byte[] sys_recv_time;      [MarshalAs(UnmanagedType.ByValArray , SizeConst = MAX_EXCHCODE_LEN)]
        public byte [] exchCode;  
         [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_VARI_LEN)]
        public byte[] varity_code;  
         [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DATE_LEN)]
        public byte[] deliv_date;  
         [MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_QUOTA_STATUS_LEN)]
        public byte[] chgStatus;   double openPrice;  
    double lastPrice;  
    double highestPrice;
    double lowestPrice;
    int     doneVolume;
    double chgPrice;
    double upperLimitPrice;
    double lowerLimitPrice;
        double hisHighestPrice;  
    double hisLowestPrice;  
    int    openInterest;  
    double preSettlePrice;  
    double preClosePrice;
    double settlePrice;
    double turnover;
     
    int preOpenInterest;  
    double closePrice;  
    double preDelta;  
    double currDelta;  


    double bidPrice1;  
    int bidVolume1;  
    double bidPrice2;  
    int bidVolume2;  
    double bidPrice3;  
    int bidVolume3;
    double bidPrice4;  
    int bidVolume4;  
    double bidPrice5;  
    int bidVolume5;   double askPrice1;  
    int askVolume1;  
    double askPrice2;  
    int askVolume2;  
    double askPrice3;  
    int askVolume3;  
    double askPrice4;  
    int askVolume4;  
    double askPrice5;
    int askVolume5;  
    }
      public void GetInfo()
            {
                //try
                //{
                while (procRtn)
                {                KSFT_QUOTA_PUBDATA_ITEM[] struc_Data = new KSFT_QUOTA_PUBDATA_ITEM[50];
                    int size = 20000;//Marshal.SizeOf(struc_Data[0]) * 50;
                    StringBuilder errMsg = new StringBuilder(1024);
                    IntPtr OutAry = IntPtr.Zero;
                    int quotaCount = 0;
                    quotaCount = KSFTHQPUB_GetQuota(OutAry, size, 2000, errMsg);
                    IntPtr current = OutAry;
                    if (quotaCount < 0)
                    {
                        lbstate.Text = "接收发生错误了";
                    }
                    else if (quotaCount > 0)
                    {
                        lbstate.Text = "正在获得数据";
                        lbErrMsg.Text = quotaCount.ToString();
                        for (int i = 0; i < quotaCount; i++)
                        {
                            struc_Data[i] = new KSFT_QUOTA_PUBDATA_ITEM();
                            Marshal.PtrToStructure(current, struc_Data[i]);
                            //for (int k = 0; k < struc_Data.Length - 1; i++)
                            //{
                            //    for (int j = 0; j < struc_Data[i].exchCode.Length - 1; j++)
                            //    {
                            //        MessageBox.Show(struc_Data[i].exchCode[j].ToString());
                            //    }
                            //}
                            Marshal.DestroyStructure(current, typeof(KSFT_QUOTA_PUBDATA_ITEM));//毁坏结构
                            //current = IntPtr.op_explicit(current.ToInt32() + Marshal.SizeOf(struc_Data[i]));
                            current = (IntPtr)(current.ToInt32() + Marshal.SizeOf(struc_Data[i])); //移动指针
                        }
                        Marshal.FreeCoTaskMem(OutAry);//释放内存                    //bindDl(datasize);
                        //this.Invoke(new BindDl(bindDl), new object[] { datasize });
                    }
                    else { lbstate.Text = "没有获得数据"; }
                    //             }
            }
            //catch (Exception e)
            //{
            //    MessageBox.Show(e.ToString());
            //}
            //}
      

  14.   

    在C++中的用法
    void ShowQuotaInfo(KSFT_QUOTA_PUBDATA_ITEM* quotaData, int quotaCount)
    {
    for (int i = 1; i <= quotaCount; ++i)
    {
    cout<<"index["<<i<<"]"<<","
    <<quotaData->contract_id<<","
    <<quotaData->upd_serial<<","
    <<quotaData->sys_recv_time<<","
    <<quotaData->exchCode<<","
    <<quotaData->varity_code<<","
    <<quotaData->deliv_date<<","
    <<quotaData->openPrice<<","
    <<quotaData->lastPrice<<","
    <<quotaData->highestPrice<<","
    <<quotaData->lowestPrice<<","
    <<quotaData->doneVolume<<","
    <<quotaData->chgPrice<<","
    <<quotaData->upperLimitPrice<<","
    <<quotaData->lowerLimitPrice<<","
    <<quotaData->hisHighestPrice<<","
    <<quotaData->hisLowestPrice<<","
    <<quotaData->openInterest<<","
    <<quotaData->preSettlePrice<<","
    <<quotaData->preClosePrice<<","
    <<quotaData->settlePrice<<","
    <<quotaData->turnover<<","
    <<quotaData->bidPrice1<<","
    <<quotaData->bidVolume1<<","
    <<quotaData->askPrice1<<","
    <<quotaData->askVolume1
    <<endl;
    quotaData++;
    }
    }//调用主程序
    int main(int argc, char* argv[])
    {
    int udpPort = 32010;
    char errorMsg[256] = "";
    bool procRtn = false;
    //启动行情接收
    procRtn = KSFTHQPUB_Start(udpPort,errorMsg);
    if (!procRtn)
    {
    cout<<errorMsg<<endl;
    return -1;
    }

    int timeOut = 2000;//超时时间2000ms
    const int MAX_QUOTA_ITEM_COUNT = 50;
    KSFT_QUOTA_PUBDATA_ITEM quotaData[MAX_QUOTA_ITEM_COUNT];

    while (true)
    {
    //接收行情,可能同时返回多条行情,函数返回值会告诉返回了几条行情
    int quotaCount = KSFTHQPUB_GetQuota((unsigned char*)quotaData, sizeof(KSFT_QUOTA_PUBDATA_ITEM)*MAX_QUOTA_ITEM_COUNT,
    timeOut, errorMsg);
    if (quotaCount < 0)
    {
    //接收发生错误了
    cout<<errorMsg<<endl;
    }
    else if (quotaCount > 0)
    {
    //接收到数据
    cout<<"recv quotaCount = "<<quotaCount<<endl;
    ShowQuotaInfo(quotaData, quotaCount);
    }
    else
    {
    //接收数据超时,没有行情数据
    cout<<"no quota data!"<<endl;
    }
    }

    KSFTHQPUB_Stop();
    return 0;
    }
      

  15.   

    搞不懂To Fly,继续在线等吧俺没法。。
      

  16.   

    太长了,没有耐心继续看完。
    看了最后一段C++对KSFTHQPUB_GetQuota的调用,如下:int quotaCount = KSFTHQPUB_GetQuota((unsigned char*)quotaData, sizeof(KSFT_QUOTA_PUBDATA_ITEM)*MAX_QUOTA_ITEM_COUNT,
    timeOut, errorMsg);缓冲区应该是先分配好的。你在C#中的调用代码如下:
    IntPtr OutAry = IntPtr.Zero;
    int quotaCount = 0;
    quotaCount = KSFTHQPUB_GetQuota(OutAry, size, 2000, errMsg);这个地方的意思是KSFTHQPUB_GetQuota函数负责分配空间,然后将分配的空间的句柄(将就着这么叫)返回。从代码上看,这个和C++的调用有很大的区别,具体到程序中就是在0x00000000这个地址写返回数据了,这个
    应该不是你想要的。建议先定以KSFT_QUOTA_PUBDATA_ITEM[] struc_Data = new KSFT_QUOTA_PUBDATA_ITEM[50],然后Marshal这个结构数组得到一个IntPtr,将这个IntPtr传到KSFTHQPUB_GetQuota中试试,或许能够成功;
      

  17.   

    当然能够使用C++/CLI就更好了,直接分装成自己要的函数的DLL,在C#中直接调用。
      

  18.   

    新进展.不过还是有错.字节数组获得了数据。如何得到??  [DllImport("KsFtQtPub.dll", EntryPoint = "KSFTHQPUB_GetQuota", CharSet = CharSet.Auto)]
            public static extern int KSFTHQPUB_GetQuota( byte[] databuf, int bufsize, int timeOut, string errorMsg);
    public void GetInfo()
            {
                //KSFT_QUOTA_PUBDATA_ITEM itemsize = new KSFT_QUOTA_PUBDATA_ITEM();
                //int a = Marshal.SizeOf(itemsize)*50;
                //MessageBox.Show(a.ToString());
                while (procRtn)
                {                byte[] datasize = new byte[16900];
                    KSFT_QUOTA_PUBDATA_ITEM[] struc_Data = new KSFT_QUOTA_PUBDATA_ITEM[50];
                    datasize[0] = Convert.ToByte(0);
                    string errMsg = "";
                    int quotaCount = KSFTHQPUB_GetQuota(datasize, 16900, 2000, errMsg);
                    if (quotaCount < 0)
                    {
                        lbstate.Text = "接收发生错误了";
                    }
                    else if (quotaCount > 0)
                    {
                        lbstate.Text = "正在获得数据";
                        lbErrMsg.Text = quotaCount.ToString();
                        IntPtr ptr=(IntPtr )datasize [0] ;
                        for (int i = 0; i <= quotaCount; i++)
                        {
                            Marshal.Copy(datasize, 0, ptr, 338);
                            Marshal.PtrToStructure(ptr, struc_Data[i]);
                            for (int k = 0; k < struc_Data.Length - 1; i++)
                            {
                                for (int j = 0; j < struc_Data[i].exchCode.Length - 1; j++)
                                {
                                    MessageBox.Show(struc_Data[i].exchCode[j].ToString());
                                }
                            }
                            Marshal.DestroyStructure(ptr, typeof(KSFT_QUOTA_PUBDATA_ITEM));//毁坏结构
                            ptr  = (IntPtr)(ptr.ToInt32() + Marshal.SizeOf(struc_Data[i])); //移动指针
                        }
                    }
                    else
                        lbstate.Text = "没有获得数据";
                        //MessageBox.Show("0");            }
            }
      

  19.   

    有没有谁知道c++中的vector怎么被c#调用阿!
      

  20.   

    顶 Mephisto_76 。楼主的代码修改前和修改后都没有整明白数据buffer的内存从哪里来。修改前:
     KSFT_QUOTA_PUBDATA_ITEM[] datasize = new KSFT_QUOTA_PUBDATA_ITEM[50]; 
    datasize的size可以认为是50×sizeof(ptr)=200,而你要的是50×sizeof(ITEM)=2000;C#的数组定义使用错误。修改后:
    同上问题依然。另外IntPtr OutAry = IntPtr.Zero;
    quotaCount = KSFTHQPUB_GetQuota(OutAry, size, 2000, errMsg);Outary的内存谁来分配,按照你在C++中的用法可以猜测是外部分配,如你使用当然是“尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”了
      

  21.   

    如果已经得到了datasize的值,可以试试下面的方法(没有开发环境,不能帮你验证——不好意思)。将你的代码中如下部分:IntPtr ptr=(IntPtr )datasize [0] ;
    for (int i = 0; i <= quotaCount; i++)
    {
        Marshal.Copy(datasize, 0, ptr, 338);
        Marshal.PtrToStructure(ptr, struc_Data[i]);
    改成:int x_size = Marshal.SizeOf( KSFT_QUOTA_PUBDATA_ITEM );for( int i = 0; i < quotaCount;++i )
    {
         InPtr ptr = Marshal.AllocHGlobal( Marshal.SizeOf( x_size ) );
         Marshal.Copy( datasize, i * x_size, ptr, struc_Data[i] );
         Marshal.FreeGlobal( ptr );
    }上面的代码要判断quotaCount <=50。
    如果还是不成,new 一个KSFT_QUOTA_PUBDATA_ITEM临时对象,然后把数据拷贝到该对象的数组即
    struc_Data[i]中。要及时揭帖哦。
      

  22.   

    晕,分心写错了。
    int x_size = Marshal.SizeOf( KSFT_QUOTA_PUBDATA_ITEM );for( int i = 0; i  < quotaCount;++i )
    {
         InPtr ptr = Marshal.AllocHGlobal( Marshal.SizeOf( x_size ) );
         Marshal.Copy( datasize, i * x_size, ptr, x_size );
         Marshal.PtrToStructure( ptr, struc_Data[i] );
         Marshal.FreeGlobal( ptr );
    } 上面的代码要判断quotaCount<=50。
    如果还是不成,new 一个KSFT_QUOTA_PUBDATA_ITEM临时对象,然后把数据拷贝到该对象的数组即
    struc_Data[i]中。多试几次,应该不成问题的。
      

  23.   

    尝试访问受保护的内存,想想看什么情况会产生,指针越界?友情提示:c#与 vc++中的变量类型是有所不同的。我遇到过由此引起的内存访问出错问题。=======================================================================
    c#: int :32位
    c++:int :16位=======================================================================没仔细看完代码,建议楼主下回贴代码时适当去掉一些
      

  24.   


            /// <summary>
            /// 判断条件
            /// </summary>
            public static bool procRtn = false;
             /// <summary>
             /// 建立新进程
             /// </summary>
            public Thread _GetInfoTh = new Thread(GetInfo);
            /// <summary>
            /// 获得数据
            /// </summary>
            /// <param name="sender"></param>
            /// <param name="e"></param>
            private void BtnGetInfo_Click(object sender, EventArgs e)
            {
                _GetInfoTh.Start();
            }
    ///获得数据
           public static void GetInfo()
            {
                while (procRtn)
                {
                                    byte[] datasize = new byte[16900];
                    KSFT_QUOTA_PUBDATA_ITEM data = new KSFT_QUOTA_PUBDATA_ITEM();
                    KSFT_QUOTA_PUBDATA_ITEM[] struc_Data = new KSFT_QUOTA_PUBDATA_ITEM[50];
                    datasize[0] = Convert.ToByte(0);
                    string errMsg = "";
                    int quotaCount = KSFTHQPUB_GetQuota(datasize, 16900, 2000, errMsg);
                    if (quotaCount < 0)
                    {
                       MessageBox.Show ("接收发生错误了");
                    }
                    else if (quotaCount > 0)
                    {
                        IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(data ) + 1);
                        for (int i = 0; i < quotaCount; i++)
                        {
                            Marshal.Copy(datasize, 0, ptr, 338);
                            struc_Data [i]=(KSFT_QUOTA_PUBDATA_ITEM ) Marshal.PtrToStructure(ptr, typeof (KSFT_QUOTA_PUBDATA_ITEM ));
                                for (int j = 0; j < struc_Data[i].exchCode.Length-1 ; j++)
                                {
                                    if (int.Parse ( struc_Data[i].exchCode[0].ToString () )!= 0)
                                    {
                                        MessageBox.Show("交易所:" + struc_Data[i].exchCode[0].ToString() + "品种代码" + struc_Data[i].varity_code[0].ToString() + "买入价" + struc_Data[i].bidPrice1 + "买入价" + struc_Data[i].bidPrice2 + "买入量" + struc_Data[i].bidVolume1 + "卖出价" + struc_Data[i].askPrice1 + "卖出量" + struc_Data[i].askVolume1);                                }
                                }
                                        Marshal.DestroyStructure(ptr, typeof(KSFT_QUOTA_PUBDATA_ITEM));//毁坏结构
                                        ptr = (IntPtr)(ptr.ToInt32() + Marshal.SizeOf(struc_Data[i])); //移动指针
                        }
                    }
                    else
                         MessageBox.Show("没有行情数据!");            }
            }//停止接受数据
            private void BtnStopInfo_Click(object sender, EventArgs e)
            {            bool c = KSFTHQPUB_Stop();
                procRtn = false;
                AutoResetEvent w = new AutoResetEvent(true);
                w.WaitOne(20, false);
                _GetInfoTh.Abort();
                if (c)
                {
                    MessageBox.Show("已停止接收行情!", "提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                }
                else
                {
                    MessageBox.Show("停止失败", "错误", MessageBoxButtons.OK, MessageBoxIcon.Error);
                }
            }如果这样写.占内存好大.不能正常关闭程序..
      

  25.   

    首先你是用IntPtr ptr = Marshal.AllocCoTaskMem(Marshal.SizeOf(data ) + 1);这样的语句在COM堆上分配了内存内存,释放这一块内存的方法应该是Marshal.FreeCoTaskMem方法。用Marshal.DestroyStructure方法能不能释
    放这块内存很难讲,所以有可能造成内存泄漏。
    第二,我觉得
    Marshal.Copy(datasize, 0, ptr, 338);/
    ptr = (IntPtr)(ptr.ToInt32() + Marshal.SizeOf(struc_Data[i])); 这两句也是不对的,这里它始终将datasize开始处长度为338个字节的内容拷贝到不同的struct_Data[i]中,而
    不是通常直觉上的是一次将datasize的所有内容拷贝到struct_Data这样一个数组结构中去。这两个地方可能都需要修改一下,然后再看看。
      

  26.   

    TO:楼上:
    ptr = (IntPtr)(ptr.ToInt32() + Marshal.SizeOf(struc_Data[i]));  
    这句是不是得不到正确的地址啊
    我有一个和楼主差不多一样的程序,可是数组长度为1时是对的,但是长度大于1时,
    第一个也是对的,但是读不到第二个以后的数据
    怎么写才是对的?
    急!
      

  27.   

    To chenshizhencong:
    你在你的struct定义上加上这个属性看看。
    [StructLayout(LayoutKind.Sequential, Pack = 1)乍一看,ptr = (IntPtr)(ptr.ToInt32() + Marshal.SizeOf(struc_Data[i])); 这句是对的。但是实际上32位CPU为了取得最大的效率,基本上都是以4个字节(32位)作为对齐的,如果有个结构的实例不是四个字节的整数倍,它会自动补齐,以使总线存取效能达到最佳。上面这个加法就会错位了,取得的是一些无用的填充数据,构建对象时就可能会失败(不会失败则是自己倒霉了,因为不知道什么时候它会当掉)。加上上面一句以后,就是告诉编译器,你不要给我操心了,我自己会解决对齐问题,我将使得每个结构以内存空间布局。这样就可以解决这样的问题。在C和C++中的解决方法是#pragma pack(1)。
      

  28.   

    To 楼上:
      我刚刚试过了,还是不可以,你帮我看一下是不是结构的定义有问题:
      [StructLayout(LayoutKind.Sequential, CharSet = CharSet.Auto,Pack=1)]
            public struct systemtime
            {
                public int wyear;
                public int wmonth;
                public int wdayofweek;
                public int wday;
                public int whour;
                public int wminute;
                public int wsecond;
                public int wmilliseconds;
            }
       
       [StructLayout(LayoutKind.Sequential,CharSet=CharSet.Auto,Pack=1)]
            public struct JOB_INFO_1
            {
                public int JobId;
                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 70)]
                public byte[] pPrinterName;
                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 70)]
                public byte[] pMachineName;
                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 70)]
                public byte[] pUserName;
                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 70)]
                public byte[] pDocument;
                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 70)]
                public byte[] pDatatype;
                [MarshalAs(UnmanagedType.ByValArray, SizeConst = 70)]
                public byte[] pStatus;
                public int Status;
                public int Priority;
                public int Position;
                public int TotalPages;
                public int PagesPrinted;
                public systemtime Submitted;
            }
     这个程序我已经调试了很多次了,数组长度为一时,就没有问题,但是大于1,就是有错.[MarshalAs(UnmanagedType.ByValArray, SizeConst = 70)]
                public byte[] pStatus; 把这部分改为public string pStatus就是报平台调用错误
    晕死了,麻烦大家帮帮忙了!
      

  29.   

    你能不能把你的非托管函数的签名列出来?
    我感觉这个结构定义都没有问题。
    不能用string的原因在于,你是要获取一个值并且把它存储在结构体中,而在.NET中,string始终是一个不能变化的存储空间,也就是不能往里写值,所以需要换用其它类型,如byte[]、StringBuilder等。
      

  30.   

    To: Mephisto_76
       我要用C#做一个打印机监控程序,实时监控的可能我是做不到了,幸好老大说定时监控的也可以,呵呵,但就是这个问题还没有搞定,我的所有非托管函数的签名:
       [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
            private static extern bool OpenPrinter(string pPrinterName,
                out IntPtr hPrinter, IntPtr pDefault);        [DllImport("winspool.drv", CharSet =CharSet.Auto, SetLastError = true)]
            private static extern bool ClosePrinter(IntPtr hPrinter);        [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
            private static extern bool GetPrinter(IntPtr hPrinter, int dwLevel,
                IntPtr pPrinter, int cbBuf, out int pcbNeeded);        [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true,
                CallingConvention=CallingConvention.Cdecl)]
            private static extern bool EnumJobs(IntPtr hPrinter, int firstJob,
                int noJobs, int Level,IntPtr lpJobs, int cbBuf,
                out int pcbNeeded, out int Returned);        [DllImport("kernel32.dll", EntryPoint = "RtlZeroMemory")]
            public static extern bool ZeroMemory(IntPtr Destination, int Length);        [DllImport("winspool.drv", CharSet = CharSet.Auto, SetLastError = true)]
            public static extern bool AddMonitor(string pName, int Level, out IntPtr pMonitors);帮帮看看有问题,怎么才可以把那个结构数组正确地读出来啊,急死了都!谢谢!
      

  31.   

    To chenshizhencong:
    根据你给出的Native函数,我看了一下MSDN相关的文档,发现你的结构定义实际上是错误的。你可以分别在C++和C#中分别用sizeof(JOB_INFO_1)和Marshal.Sizeof( typeof(JOB_INFO_1) )看看,只有一个元素的时候碰巧对了。错误是这样的,在Native中(C/C++)中,JOB_INFO_1定义如下:
    typedef struct _JOB_INFO_1 { 
      DWORD  JobId; 
      LPTSTR pPrinterName; 
      LPTSTR pMachineName; 
      LPTSTR pUserName; 
      LPTSTR pDocument; 
      LPTSTR pDatatype; 
      LPTSTR pStatus; 
      DWORD  Status; 
      DWORD  Priority; 
      DWORD  Position; 
      DWORD  TotalPages; 
      DWORD  PagesPrinted; 
      SYSTEMTIME Submitted; 
    } JOB_INFO_1, *PJOB_INFO_1;这里边pPrinterName、PMachineName、pUserName、pDocument、pDatatype、pStatus这几个成员都是LPTSTR类型,也就是TCHAR*,它们每个都占用了4个字节的空间。你的结构定义表示的内存布局是(C/C++)描述:#define BUFFER_SIZE 70typedef struct _JOB_INFO_1 { 
      DWORD  JobId; 
      char pPrinterName[BUFFER_SIZE]; 
      char pMachineName[BUFFER_SIZE]; 
      char pUserName[BUFFER_SIZE]; 
      char pDocument[BUFFER_SIZE]; 
      char pDatatypep[BUFFER_SIZE]; 
      char pStatus[BUFFER_SIZE]; 
      DWORD  Status; 
      DWORD  Priority; 
      DWORD  Position; 
      DWORD  TotalPages; 
      DWORD  PagesPrinted; 
      SYSTEMTIME Submitted; 
    } JOB_INFO_1, *PJOB_INFO_1;
      

  32.   

    它们其实是不同的,你把你的结构中类似
    [MarshalAs(UnmanagedType.ByValArray, SizeConst = 70)]
    public byte[] pPrinterName; 
    的定义改成IntPtr之类的东西试试。
      

  33.   

    [StructLayout(LayoutKind.Sequential)]
    private struct SYSTEMTIME {
      [MarshalAs(UnmanagedType.U2)] public short Year;
      [MarshalAs(UnmanagedType.U2)] public short Month;
      [MarshalAs(UnmanagedType.U2)] public short DayOfWeek;
      [MarshalAs(UnmanagedType.U2)] public short Day;
      [MarshalAs(UnmanagedType.U2)] public short Hour;
      [MarshalAs(UnmanagedType.U2)] public short Minute;
      [MarshalAs(UnmanagedType.U2)] public short Second;
      [MarshalAs(UnmanagedType.U2)] public short Milliseconds;
    }struct JOB_INFO_1 {
       public UInt32 JobId;
       public string pPrinterName;
       public string pMachineName;
       public string pUserName;
       public string pDocument;
       public string pDatatype;
       public string pStatus;
       public UInt32 Status;
       public UInt32 Priority;
       public UInt32 Position;
       public UInt32 TotalPages;
       public UInt32 PagesPrinted;
       public SYSTEMTIME Submitted;
    }[DllImport("winspool.drv", CharSet=CharSet.Auto)]
    public static extern bool OpenPrinter( string pPrinterName, out IntPtr
    phPrinter, IntPtr pDefault );[DllImport("winspool.drv", CharSet=CharSet.Auto)]
    public static extern bool ClosePrinter( IntPtr hPrinter // handle to printer
    object );[DllImport("winspool.drv", CharSet=CharSet.Auto)]
    public static extern int EnumJobs( IntPtr hPrinter, int FirstJob, int
    NoJobs, int Level, IntPtr pInfo, int cdBuf, out int pcbNeeded, out int
    pcReturned);public void test()
    {
        IntPtr handle;
        int FirstJob = 1;
        int NumJobs = 2;
        int pcbNeeded;
        int pcReturned;    OpenPrinter ( @"\\server1\psc750", out handle, IntPtr.Zero );    EnumJobs ( handle, FirstJob, NumJobs, 1, IntPtr.Zero, 0, out pcbNeeded,
    out pcReturned);    IntPtr pData = Marshal.AllocHGlobal ( pcbNeeded );    EnumJobs ( handle, FirstJob, NumJobs, 1, pData, pcbNeeded, out
    pcbNeeded, out pcReturned);    JOB_INFO_1 [] jobs = new JOB_INFO_1[pcReturned];    int pTemp = pData.ToInt32();     for (int i=0; i<pcReturned; ++i)
        {
            jobs[i] = (JOB_INFO_1) Marshal.PtrToStruct( new IntPtr(pTemp),
    typof(JOB_INFO_1) );
            pTemp+= Marshal.SizeOf( typeof (JOB_INFO_1 );
        }    Marshal.FreeHGlobal ( pData );    ClosePrinter ( handle );
    } 试试上面这段代码?
      

  34.   

    TO 楼上:
       谢谢你啊,我按照你说的方法试了,可以,呵呵,不过结构数组中读到的string数据部分是乱码,知道的话再帮我看下??
    我自己也再找找,真的很谢谢你!