标签归档:C#

C#实现的HttpSQS客户端封装类

[csharp]
class HttpSQSClient
{
private String server, port, charset;

public HttpSQSClient(String server, String port, String charset)
{
this.server = server;
this.port = port;
this.charset = charset;
}

private string DoProcess(String urlstr)
{
string result = String.Empty;

Uri url = null;
try
{
url = new Uri(urlstr);
}
catch (Exception e)
{
return "The httpsqs server must be error";
}

try
{
HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "get";

HttpWebResponse response = (HttpWebResponse)request.GetResponse();
System.Text.Encoding encode;
try
{
encode = System.Text.Encoding.GetEncoding(response.CharacterSet);
}
catch
{
encode = System.Text.Encoding.Default;
}

System.IO.Stream stream = response.GetResponseStream();
System.IO.StreamReader read = new System.IO.StreamReader(stream, encode);
result = read.ReadToEnd();

response.Close();

return result;
}
catch (IOException ex)
{
return "Get data error";
}
}

public String MaxQueue(String queue_name, String num)
{
String urlstr = "http://" + this.server + ":" + this.port + "/?name="
+ queue_name + "&opt=maxqueue&num=" + num;

String result = null;

result = this.DoProcess(urlstr);
return result;
}

public String Reset(String queue_name)
{
String urlstr = "http://" + this.server + ":" + this.port + "/?name="
+ queue_name + "&opt=reset";
String result = null;

result = this.DoProcess(urlstr);
return result;
}

public String View(String queue_name, String pos)
{
String urlstr = "http://" + this.server + ":" + this.port
+ "/?charset=" + this.charset + "&name=" + queue_name
+ "&opt=view&pos=" + pos;
String result = null;

result = this.DoProcess(urlstr);
return result;
}

public String Status(String queue_name)
{
String urlstr = "http://" + this.server + ":" + this.port + "/?name="
+ queue_name + "&opt=status";
String result = null;

result = this.DoProcess(urlstr);
return result;
}

public String Get(String queue_name)
{
String urlstr = "http://" + this.server + ":" + this.port
+ "/?charset=" + this.charset + "&name=" + queue_name
+ "&opt=get";
String result = null;

result = this.DoProcess(urlstr);
return result;
}

public String Put(String queue_name, String data)
{
String ret = String.Empty;
String urlstr = "http://" + this.server + ":" + this.port + "/?name="
+ queue_name + "&opt=put";
Uri url = null;
try
{
url = new Uri(urlstr);
}
catch (Exception)
{
return "The httpsqs server must be error";
}

HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(url);
request.Method = "post";
byte[] requestBytes = System.Text.Encoding.UTF8.GetBytes(data);
request.ContentType = "application/x-www-form-urlencoded";
request.ContentLength = requestBytes.Length;
request.Timeout = 6000;
try
{
Stream requestStream = request.GetRequestStream();
requestStream.Write(requestBytes, 0, requestBytes.Length);
requestStream.Close();

HttpWebResponse response = (HttpWebResponse)request.GetResponse();
StreamReader reader = new StreamReader(response.GetResponseStream(), System.Text.Encoding.Default);
ret = reader.ReadToEnd();
}
catch (Exception)
{
return "Put data error";
}

return ret;
}
}
[/csharp]

除了put方法使用post方式请求外,其他方法都用post方式。

编译boost1.43.0

编译boost1.43.0 with icu 支持regex unicode编码
安装icu,即IBM的一个通用的转码库
wget http://downloads.sourceforge.net/project/icu/ICU4C/4.0/icu4c-4_0-src.tgz?use_mirror=cdnetworks-kr-2
tar zxvf icu4c-4_0-src.tgz
cd icu/source
./configure –prefix=/usr
make
make install
ldconfig
下载安装boost

wget http://sourceforge.net/projects/boost/files/boost/1.43.0/boost_1_43_0.tar.gz/download
tar zxvf boost_1_43_0.tar.gz
cd boost_1_43_0
rm -rf /usr/include/boost/
rm -rf /usr/lib/libboost*
./bootstrap.sh
./bjam -sHAVE_ICU=1
编译大概半小时,完成后:
cp ./stage/lib/* /usr/lib
cp ./boost /usr/include/
ldconfig
以前我使用bjam install –prefix=/usr但特别慢,有的时候lib下的东西copy不过去。现在我编译完直接cp过去,一点问题没有。

用实例讲解Variant类型在VB、C#、VC中的参数传递[转]

几年前我用VB开发了一个西门子PPI通信控件,由于VB开发的控件是标准的COM组件,所以想当然的认为VC、C#、Delphi等开发语言可以非常容易的使用。

前段时间由于该控件基于微软的MSCOMM控件,这个控件如果系统没有安装VB,单独注册好像很难成功,这害的一些没有装VB的用户,为了这个小控件必须安装一次VB,这实在是划算不来,所以直接用API串口函数进行了封装改进,这样不仅效率提高了,并且再也不需要MSCOMM控件了。

这一次,我不仅使该控件支持了浮点运算,并且在VC、C#(VB当然就不用多试了,以前就很好的支持)进行了兼容测试。

一试问题就来了,没有改进之前的控件,由于C#封装性能甚好,还能使用,唯一不足的是,控件方法中如果不要求返回的参数前面没有添加ByVal参数,在C#中就转换为 ref ***,害的你还得专门定义临时变量进行传参。

在VC中直接就不行,ReadData和WriteData等几个主要方法根本在VC中无法转换成对应函数,具体错误信息如下:

// method ‘ReadData’ not emitted because of invalid return type or parameter type

// method ‘WriteData’ not emitted because of invalid return type or parameter type

// method ‘PlcLogin’ not emitted because of invalid return type or parameter type

// method ‘PlcRun’ not emitted because of invalid return type or parameter type

// method ‘PlcStop’ not emitted because of invalid return type or parameter type

经过测试,最后发现VB函数中的byte和数组在VC中根本找不到合适的对应。

由于控件中又新添加了浮点数的支持,所以对参数接口又增加了一层复杂性。突然想到微软的MSCOMM控件各语言肯定都能很好的支持,它的接口参数是怎样的定义的。我在VB、VC、C#分别试了一下,VB中和input和Output属性的类型就是Variant类型,在VC中是VARIANT,在C#中是Object。用Variant还有个好处,就是各种类型的数据都可以传输,没有必要在另外添加接口函数了。

最后我定义的接口如下(主要接口):

Public Function ReadData(ByVal lngAddr As Long, vData As Variant, Optional ByVal lngNum As Long = 1, Optional ByVal bytLen As PPILEN = PPI_B, Optional ByVal bytType As PPITYPE = PPI_V, Optional ByVal Addr As Long = 0) As Long

Public Function WriteData(ByVal lngAddr As Long, ByVal vData As Variant, Optional ByVal lngNum As Long = 1, Optional ByVal bytLen As PPILEN = PPI_B, Optional ByVal bytType As PPITYPE = PPI_V, Optional ByVal Addr As Long = 0) As Long

在VC中对应的接口如下:

long ReadData(long lngAddr, VARIANT* vData, long lngNum, long bytLen, long bytType, long Addr);

long WriteData(long lngAddr, const VARIANT& vData, long lngNum, long bytLen, long bytType, long Addr);

在C#中的接口如下:

public virtual int ReadData(int lngAddr, ref object vData);

public virtual int ReadData(int lngAddr, ref object vData, int lngNum, PPILEN bytLen, PPITYPE bytType, int addr);

public virtual int WriteData(int lngAddr, object vData);

public virtual int WriteData(int lngAddr, object vData, int lngNum, PPILEN bytLen, PPITYPE bytType, int addr);

以为这样定义就万事大吉了,事后一试我又错了,在C#中没有任何问题(看了微软还是在C#上下了很大的功夫),在VC简单的定义一个VARIANT变量直接传递给控件,VB控件老是报错,根本无法使用。后来想为什么MSCOMM控件可以,我的控件不可以。天杀的MSCOMM肯定是VC开发的,而我的控件是VB开发的,VB和C#的包容性都很强,而VC却高高在上不肯屈就。

正一筹莫展准备放弃的时候,突然想到了以前用VC开发的OPC程序,上面有很多关于VARIANT的应用,一看就明白了,原来在VC中VARIANT的用法是有讲究的。

下面我就详细说一下控件同样的接口在不同语言中如何使用。

在VB中:

Private Sub cmdReadData_Click()

On Error GoTo ToExit ‘打开错误陷阱

‘————————————————

Dim i As Long

Dim bytType As Byte

Dim lngRet As Long

Dim lngData() As Long

Dim fData() As Single

Dim vData As Variant

Select Case cmbType.ListIndex

Case 0: bytType = PPI_I

Case 1: bytType = PPI_Q

Case 2: bytType = PPI_M

Case 3: bytType = PPI_V

Case 4: bytType = PPI_S

Case 5: bytType = PPI_SM

End Select

S7_PPI1.FixAddr = cmbNo.ListIndex + 1

lngRet = S7_PPI1.ReadData(Val(txtAddr), vData, Val(cmbNum.Text), Val(cmbLen.ListIndex), Val(bytType))

If lngRet = 0 Then

txtData = “”

If cmbLen.ListIndex = 3 Then

fData = vData

For i = 1 To Val(cmbNum.Text)

txtData = txtData & Format(fData(i – 1), “0.00″) & ” ”

Next

Else

lngData = vData

For i = 1 To Val(cmbNum.Text)

txtData = txtData & Format(lngData(i – 1), “0″) & ” ”

Next

End If

Else

txtData = “Error”

End If

‘————————————————

Exit Sub

‘—————-

ToExit:

MsgBox Err.Description

End Sub

Private Sub cmdWriteData_Click()

On Error GoTo ToExit ‘打开错误陷阱

‘————————————————

Dim bytType As Byte

Dim strData() As String

Dim lngRet As Long

Dim lngData(100) As Long

Dim fData(100) As Single

Dim i As Long

Select Case cmbType.ListIndex

Case 0: bytType = PPI_I

Case 1: bytType = PPI_Q

Case 2: bytType = PPI_M

Case 3: bytType = PPI_V

Case 4: bytType = PPI_S

Case 5: bytType = PPI_SM

End Select

If Len(txtData) > 0 Then

strData = Split(txtData, ” “)

If cmbLen.ListIndex = 3 Then

For i = 0 To UBound(strData)

fData(i) = Val(strData(i))

Next

lngRet = S7_PPI1.WriteData(Val(txtAddr), fData, UBound(strData) + 1, Val(cmbLen.ListIndex), Val(bytType), cmbNo.ListIndex + 1)

Else

For i = 0 To UBound(strData)

lngData(i) = Val(strData(i))

Next

lngRet = S7_PPI1.WriteData(Val(txtAddr), lngData, UBound(strData) + 1, Val(cmbLen.ListIndex), Val(bytType), cmbNo.ListIndex + 1)

End If

If lngRet = 0 Then

Else

txtData = “Error”

End If

End If

‘————————————————

Exit Sub

‘—————-

ToExit:

MsgBox Err.Description

End Sub[SPAN]

在C#中:

/// <summary>

/// 读数据

/// </summary>

/// <param name=”sender”></param>

/// <param name=”e”></param>

private void btnRead_Click(object sender, EventArgs e)

{

int intAddr = int.Parse(txtFixAddr.Text);

object vData = new object();

/*

[PPI_I] = &H81

[PPI_Q] = &H82

[PPI_M] = &H83

[PPI_V] = &H84

[PPI_S] = 4

[PPI_SM] = 5

*/

PPIV2.PPITYPE DataType= PPIV2.PPITYPE.PPI_V;

switch (cmbDataType.SelectedIndex)  //数据类型

{

case 0:

DataType = PPIV2.PPITYPE.PPI_I;

break;

case 1:

DataType = PPIV2.PPITYPE.PPI_Q;

break;

case 2:

DataType = PPIV2.PPITYPE.PPI_M;

break;

case 3:

DataType = PPIV2.PPITYPE.PPI_V;

break;

case 4:

DataType = PPIV2.PPITYPE.PPI_S;

break;

case 5:

DataType = PPIV2.PPITYPE.PPI_SM;

break;

}

if (axS7_PPI1.ReadData(int.Parse(txtDataAddr.Text), ref vData, cmbLen.SelectedIndex+1  , (PPIV2.PPILEN)cmbDataMode.SelectedIndex, DataType, intAddr) == 0)

{

if (cmbDataMode.SelectedIndex == 3)

{

float[] fData = (float[])vData;

txtData.Text = “”;

for (int i = 0; i < fData.Length; i++)

{

txtData.Text += fData[i].ToString(“0.00″) + ” “;

}

}

else

{

Int32[] intData = (Int32[])vData;

txtData.Text = “”;

for (int i = 0; i < intData.Length; i++)

{

txtData.Text += intData[i].ToString() + ” “;

}

}

}

else

{

txtData.Text = “ERROR”;

}

}

/// <summary>

/// 写数据

/// </summary>

/// <param name=”sender”></param>

/// <param name=”e”></param>

private void btnWrite_Click(object sender, EventArgs e)

{

int intAddr = int.Parse(txtFixAddr.Text);

object vData = new object();

/*

[PPI_I] = &H81

[PPI_Q] = &H82

[PPI_M] = &H83

[PPI_V] = &H84

[PPI_S] = 4

[PPI_SM] = 5

*/

PPIV2.PPITYPE DataType = PPIV2.PPITYPE.PPI_V;

switch (cmbDataType.SelectedIndex)  //数据类型

{

case 0:

DataType = PPIV2.PPITYPE.PPI_I;

break;

case 1:

DataType = PPIV2.PPITYPE.PPI_Q;

break;

case 2:

DataType = PPIV2.PPITYPE.PPI_M;

break;

case 3:

DataType = PPIV2.PPITYPE.PPI_V;

break;

case 4:

DataType = PPIV2.PPITYPE.PPI_S;

break;

case 5:

DataType = PPIV2.PPITYPE.PPI_SM;

break;

}

long lngRet = 0;

if (cmbDataMode.SelectedIndex == 3)

{

float[] fData = new float[100];

fData[0] = float.Parse(txtData.Text);

lngRet = axS7_PPI1.WriteData(int.Parse(txtDataAddr.Text), fData, 1, (PPIV2.PPILEN)cmbDataMode.SelectedIndex, DataType, intAddr);

}

else

{

Int32[] intData = new Int32[100];

intData[0] = Int32.Parse(txtData.Text);

lngRet = axS7_PPI1.WriteData(int.Parse(txtDataAddr.Text), intData, 1, (PPIV2.PPILEN)cmbDataMode.SelectedIndex, DataType, intAddr);

}

if (lngRet != 0)

{

txtData.Text = “ERROR”;

}

}[SPAN]

在VC中:

//读数据

void CPPI_TestDlg::OnReadData()

{

//pCombo->GetLBText (pCombo->GetCurSel (), strType);

long lngFixAddr=0,lngDataAddr=0;

char strAddr[255];

m_FixAddr.GetWindowText(strAddr,255);

sscanf(strAddr,”%ld”,&lngFixAddr);

m_DataAddr.GetWindowText(strAddr,255);

sscanf(strAddr,”%ld”,&lngDataAddr);

/*

[PPI_I] = &H81

[PPI_Q] = &H82

[PPI_M] = &H83

[PPI_V] = &H84

[PPI_S] = 4

[PPI_SM] = 5

*/

long DataType;

switch (m_DataType.GetCurSel())  //数据类型

{

case 0:

DataType=0×81;

break;

case 1:

DataType=0×82;

break;

case 2:

DataType=0×83;

break;

case 3:

DataType=0×84;

break;

case 4:

DataType=0×4;

break;

case 5:

DataType=0×5;

break;

}

long lngRet;

VARIANT vData;

VariantInit (&vData);

if(m_DataMode.GetCurSel()==3)  //浮点数

{

vData.vt = VT_R4 | VT_ARRAY;

vData.parray=SafeArrayCreateVector(VT_R4, 0, 255 );

}

else

{

vData.vt = VT_I4 | VT_ARRAY;

vData.parray=SafeArrayCreateVector(VT_I4, 0, 255 );     //SAFEARRAY vd;

}

lngRet=m_PPI.ReadData(lngDataAddr,&vData,m_DataNum.GetCurSel()+1,m_DataMode.GetCurSel(),DataType,lngFixAddr);

if(lngRet==0)

{

CString strData;

if(m_DataMode.GetCurSel()==3)  //浮点数

{

float *fData;

SafeArrayAccessData(vData.parray, (void**)&fData );

for(int i=0;i<m_DataNum.GetCurSel()+1;i++)  //(int)vData.parray->cbElements

{

CString cData;

cData.Format(“%04.2f “,fData[i]);

strData+= cData;

}

SafeArrayUnaccessData(vData.parray);

}

else

{

long *lngData;

SafeArrayAccessData(vData.parray, (void**)&lngData );

for(int i=0;i<m_DataNum.GetCurSel()+1;i++)  //(int)vData.parray->cbElements

{

CString cData;

cData.Format(“%ld “,lngData[i]);

strData+= cData;

}

SafeArrayUnaccessData(vData.parray);

}

m_Data.SetWindowText(strData);

}

else

{

m_Data.SetWindowText(_T(“ERROR”));

}

SafeArrayUnaccessData(vData.parray);

SafeArrayDestroy(vData.parray);

VariantClear(&vData);

}

//写数据

void CPPI_TestDlg::OnWrite()

{

long lngFixAddr=0,lngDataAddr=0;

char strAddr[255];

m_FixAddr.GetWindowText(strAddr,255);

sscanf(strAddr,”%ld”,&lngFixAddr);

m_DataAddr.GetWindowText(strAddr,255);

sscanf(strAddr,”%ld”,&lngDataAddr);

long DataType;

switch (m_DataType.GetCurSel())

{

case 0:

DataType=0×81;

break;

case 1:

DataType=0×82;

break;

case 2:

DataType=0×83;

break;

case 3:

DataType=0×84;

break;

case 4:

DataType=0×4;

break;

case 5:

DataType=0×5;

break;

}

long lngRet;

VARIANT vData;

VariantInit (&vData);

if(m_DataMode.GetCurSel()==3)  //浮点数

{

vData.vt = VT_R4 | VT_ARRAY;

vData.parray=SafeArrayCreateVector(VT_R4, 0, 255 );

float *fDatas,fData;

SafeArrayAccessData(vData.parray, (void**)&fDatas );

m_Data.GetWindowText(strAddr,255);

sscanf(strAddr,”%f”,&fData);

fDatas[0]=fData;

SafeArrayUnaccessData(vData.parray);

}

else

{

vData.vt = VT_I4 | VT_ARRAY;

vData.parray=SafeArrayCreateVector(VT_I4, 0, 255 );     //SAFEARRAY vd;

long *lngDatas,lngData;

SafeArrayAccessData(vData.parray, (void**)&lngDatas );

m_Data.GetWindowText(strAddr,255);

sscanf(strAddr,”%ld”,&lngData);

lngDatas[0]=lngData;

SafeArrayUnaccessData(vData.parray);

}

lngRet=m_PPI.WriteData(lngDataAddr,(const VARIANT &)vData,1,m_DataMode.GetCurSel(),DataType,lngFixAddr);

if(lngRet!=0)

{

m_Data.SetWindowText(_T(“ERROR”));

}

SafeArrayUnaccessData(vData.parray);

SafeArrayDestroy(vData.parray);

VariantClear(&vData);

}

C# 结构体与类的区别[转]

struct 类型是一种值类型,通常用来封装小型相关变量组,例如,矩形的坐标或库存商品的特征。下面的示例显示了一个简单的结构声明。

public struct PostalAddress
{
// Fields, properties, methods and events go here…
}

结构与类共享几乎所有相同的语法,但结构比类受到的限制更多:

尽管结构的静态字段可以初始化,结构实例字段声明还是不能使用初始值设定项。

结构不能声明默认构造函数(没有参数的构造函数)或析构函数。

结构的副本由编译器自动创建和销毁,因此不需要使用默认构造函数和析构函数。实际上,编译器通过为所有字段赋予默认值(参见默认值表)来实现默认构造函数。结构不能从类或其他结构继承。

结构是值类型 — 如果从结构创建一个对象并将该对象赋给某个变量,变量则包含结构的全部值。复制包含结构的变量时,将复制所有数据,对新副本所做的任何修改都不会改变旧副本的数据。由于结构不使用引用,因此结构没有标识 — 具有相同数据的两个值类型实例是无法区分的。C# 中的所有值类型本质上都继承自 ValueType,后者继承自 Object。

编译器可以在一个称为装箱的过程中将值类型转换为引用类型。

结构具有以下特点:

结构是值类型,而类是引用类型

向方法传递结构时.结构是通过传值方式传递的,不是作为引用方式传递.

与类不同,结构的实例化可以不使用new运算符.

结构可以声明构造函数,但他们必须带参数

一个结构不能从另一个结构或类继承,而且不能作为一个类的基。所有结构都直接继承自 System.ValueType,后者继承自 System.Object。

结构可以实现接口。

在结构中初始化实例字段是错误的。