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());
}
}
错误信息: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
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());
}
}
错误信息: 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
c++里用sizeof()函数
C#里用Marshal.SizeOf()方法如果不一样,再逐条分析是那个字段出的问题。ps:也需要保证两边的结构对齐方式一致
[StructLayout(LayoutKind.Sequential, Pack = 1)]
在这句出错了 int size = Marshal.SizeOf(struc_Data[0]) * 50;
类型“AutoTransaction.FrmMain+KSFT_QUOTA_PUBDATA_ITEM”不能作为非托管结构进行封送处理;无法计算有意义的大小或偏移量。
[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;
}
c++里用sizeof()函数
C#里用Marshal.SizeOf()方法
获得大小是一样的
在这句出错了 int size = Marshal.SizeOf(struc_Data[0]) * 50;
类型“AutoTransaction.FrmMain+KSFT_QUOTA_PUBDATA_ITEM”不能作为非托管结构进行封送处理;无法计算有意义的大小或偏移量。
我这句估计了个.没有报错.我去内网测试下来
quotaCount = KSFTHQPUB_GetQuota(OutAry, size, 2000, errMsg);
尝试读取或写入受保护的内存。这通常指示其他内存已损坏。
[MarshalAs(UnmanagedType.LPStr, SizeConst = MAX_DATE_LEN)]
public string sys_recv_time;我的
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DATE_LEN)]
public byte[] sys_recv_time;
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());
//}
//}
}
public StringBuilder sys_recv_time; //行情服务器收到行情的时间,行情服务器唯一维护,格式:HH:MM:SS
啥也不说了。
[MarshalAs(UnmanagedType.ByValArray, SizeConst = MAX_DATE_LEN)]
public byte[] sys_recv_time;
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());
//}
//}
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;
}
看了最后一段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中试试,或许能够成功;
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"); }
}
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++中的用法可以猜测是外部分配,如你使用当然是“尝试读取或写入受保护的内存。这通常指示其他内存已损坏。”了
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]中。要及时揭帖哦。
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]中。多试几次,应该不成问题的。
c#: int :32位
c++:int :16位=======================================================================没仔细看完代码,建议楼主下回贴代码时适当去掉一些
/// <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);
}
}如果这样写.占内存好大.不能正常关闭程序..
放这块内存很难讲,所以有可能造成内存泄漏。
第二,我觉得
Marshal.Copy(datasize, 0, ptr, 338);/
ptr = (IntPtr)(ptr.ToInt32() + Marshal.SizeOf(struc_Data[i])); 这两句也是不对的,这里它始终将datasize开始处长度为338个字节的内容拷贝到不同的struct_Data[i]中,而
不是通常直觉上的是一次将datasize的所有内容拷贝到struct_Data这样一个数组结构中去。这两个地方可能都需要修改一下,然后再看看。
ptr = (IntPtr)(ptr.ToInt32() + Marshal.SizeOf(struc_Data[i]));
这句是不是得不到正确的地址啊
我有一个和楼主差不多一样的程序,可是数组长度为1时是对的,但是长度大于1时,
第一个也是对的,但是读不到第二个以后的数据
怎么写才是对的?
急!
你在你的struct定义上加上这个属性看看。
[StructLayout(LayoutKind.Sequential, Pack = 1)乍一看,ptr = (IntPtr)(ptr.ToInt32() + Marshal.SizeOf(struc_Data[i])); 这句是对的。但是实际上32位CPU为了取得最大的效率,基本上都是以4个字节(32位)作为对齐的,如果有个结构的实例不是四个字节的整数倍,它会自动补齐,以使总线存取效能达到最佳。上面这个加法就会错位了,取得的是一些无用的填充数据,构建对象时就可能会失败(不会失败则是自己倒霉了,因为不知道什么时候它会当掉)。加上上面一句以后,就是告诉编译器,你不要给我操心了,我自己会解决对齐问题,我将使得每个结构以内存空间布局。这样就可以解决这样的问题。在C和C++中的解决方法是#pragma pack(1)。
我刚刚试过了,还是不可以,你帮我看一下是不是结构的定义有问题:
[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就是报平台调用错误
晕死了,麻烦大家帮帮忙了!
我感觉这个结构定义都没有问题。
不能用string的原因在于,你是要获取一个值并且把它存储在结构体中,而在.NET中,string始终是一个不能变化的存储空间,也就是不能往里写值,所以需要换用其它类型,如byte[]、StringBuilder等。
我要用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);帮帮看看有问题,怎么才可以把那个结构数组正确地读出来啊,急死了都!谢谢!
根据你给出的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;
[MarshalAs(UnmanagedType.ByValArray, SizeConst = 70)]
public byte[] pPrinterName;
的定义改成IntPtr之类的东西试试。
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 );
} 试试上面这段代码?
谢谢你啊,我按照你说的方法试了,可以,呵呵,不过结构数组中读到的string数据部分是乱码,知道的话再帮我看下??
我自己也再找找,真的很谢谢你!