广告位联系
返回顶部
分享到

Qt(C++)调用工业相机Basler的SDK使用教程

C#教程 来源:互联网搜集 作者:秩名 发布时间:2020-03-05 21:52:54 人浏览
摘要

简介 由于公司采购的AVT相机不足,需要用Basler相机来弥补,所以我也了解了一下Basler这款相机的SDK。由于Basler这边的相机提供的没有提供Qt的示例,所以我做一个分享出来。 本篇的Demo采用的是工业黑白相机。工业应用中,如果我们要处理的是与图像颜色有关

简介

由于公司采购的AVT相机不足,需要用Basler相机来弥补,所以我也了解了一下Basler这款相机的SDK。由于Basler这边的相机提供的没有提供Qt的示例,所以我做一个分享出来。

本篇的Demo采用的是工业黑白相机。工业应用中,如果我们要处理的是与图像颜色有关,那么我们最好采用彩色工业相机;如果不是,那么我们最好选用黑白工业相机,因为在同样分辨率下的工业相机,黑白工业教学精度比彩色工业相机高,尤其是在看图像边缘的时候,黑白工业相机的效果更好。

开发环境

  • Qt:  5.6.2vc2013版 
  • Basler:  5.0.11版

效果图

 上图只是做了SDK部分接口的获取和设置。相机的触发方式、曝光时间、增益、频率,以及图片的尺寸、灯的触发信号等。

Basler相机SDK接口调用控制类

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
#ifndef SBASLERCAMERACONTROL_H
#define SBASLERCAMERACONTROL_H
 
#include <QObject>
#include <pylon/PylonIncludes.h>
#include <QImage>
#include <QTimer>
 
#define DOUBLE_MAX 100000
#define DOUBLE_MIN 0
 
using namespace std;
using namespace Pylon;
using namespace GenApi;
class SBaslerCameraControl : public QObject
{
  Q_OBJECT
public:
  explicit SBaslerCameraControl(QObject *parent = 0);
  ~SBaslerCameraControl();
 
  enum SBaslerCameraControl_Type{
    Type_Basler_Freerun, //设置相机的内触发
    Type_Basler_Line1, //设置相机的外触发
    Type_Basler_ExposureTimeAbs, //设置相机的曝光时间
    Type_Basler_GainRaw, //设置相机的增益
    Type_Basler_AcquisitionFrameRateAbs, //设置相机的频率
    Type_Basler_Width, //图片的宽度
    Type_Basler_Height, //图片的高度
    Type_Basler_LineSource, //灯的触发信号
  };
  void initSome();
  void deleteAll();
  QStringList cameras();
  int OpenCamera(QString cameraSN);
  int CloseCamera();
 
  void setExposureTime(double time); // 设置曝光时间
  int getExposureTime(); // 获取曝光时间
  int getExposureTimeMin(); // 最小曝光时间
  int getExposureTimeMax(); // 最大曝光时间
 
  void setFeatureTriggerSourceType(QString type); // 设置种类
  QString getFeatureTriggerSourceType(); // 获取种类:软触发、外触发等等
 
  void setFeatureTriggerModeType(bool on); // 设置模式触发
  bool getFeatureTriggerModeType(); // 获取模式触发
  void SetCamera(SBaslerCameraControl::SBaslerCameraControl_Type index, double tmpValue = 0.0); // 设置各种参数
  double GetCamera(SBaslerCameraControl::SBaslerCameraControl_Type index); // 获取各种参数
 
  long GrabImage(QImage& image,int timeout = 2000);
  long StartAcquire(); // 开始采集
  long StopAcquire(); // 结束采集
signals:
  void sigCameraUpdate(QStringList list);
  void sigSizeChange(QSize size);
  void sigCameraCount(int count);
  void sigCurrentImage(QImage img);
private:
  void UpdateCameraList();
  void CopyToImage(CGrabResultPtr pInBuffer, QImage &OutImage);
private slots:
  void onTimerGrabImage();
private:
  CInstantCamera m_basler;
  QStringList m_cameralist;
  QString m_currentMode;
  bool m_isOpenAcquire = false; // 是否开始采集
  bool m_isOpen = false; // 是否打开摄像头
  QSize m_size;
};
 
#endif // SBASLERCAMERACONTROL_H

源文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
#include "sbaslercameracontrol.h"
#include <QDateTime>
#include <QDebug>
 
SBaslerCameraControl::SBaslerCameraControl(QObject *parent) : QObject(parent)
{
}
 
SBaslerCameraControl::~SBaslerCameraControl()
{
}
 
void SBaslerCameraControl::initSome()
{
  qDebug() << "SBaslerCameraControl: PylonInitialize initSome" ;
  PylonInitialize();
  CTlFactory &TlFactory = CTlFactory::GetInstance();
  TlInfoList_t lstInfo;
  int n = TlFactory.EnumerateTls(lstInfo);
 
  TlInfoList_t::const_iterator it;
  for ( it = lstInfo.begin(); it != lstInfo.end(); ++it ) {
    qDebug() << "FriendlyName: " << it->GetFriendlyName() << "FullName: " << it->GetFullName();
    qDebug() << "VendorName: " << it->GetVendorName() << "DeviceClass: " << it->GetDeviceClass() ;
  }
  UpdateCameraList();
  emit sigCameraCount(n);
  qDebug() << "SBasler Camera Count: " << n;
}
 
void SBaslerCameraControl::deleteAll()
{
  //停止采集
  if(m_isOpenAcquire) {
    StopAcquire();
  }
  //关闭摄像头
  CloseCamera();
  //关闭库
  qDebug() << "SBaslerCameraControl deleteAll: PylonTerminate" ;
  PylonTerminate();
  qDebug() << "SBaslerCameraControl deleteAll: Close" ;
}
 
QStringList SBaslerCameraControl::cameras()
{
  return m_cameralist;
}
 
void SBaslerCameraControl::UpdateCameraList()
{
  CTlFactory& TLFactory = CTlFactory::GetInstance();
  ITransportLayer * pTl = TLFactory.CreateTl("BaslerGigE");
  DeviceInfoList_t devices;
  int n = pTl->EnumerateDevices(devices);
  CInstantCameraArray cameraArray(devices.size());
  if(n == 0) {
    qDebug() << "Cannot find Any camera!";
    return;
  }
  for (int i=0 ; i<cameraArray.GetSize() ; i++) {
    cameraArray[i].Attach(TLFactory.CreateDevice(devices[i]));
    string sn = cameraArray[i].GetDeviceInfo().GetSerialNumber();
    m_cameralist << QString::fromStdString(sn);
  }
  emit sigCameraUpdate(m_cameralist);
}
 
void SBaslerCameraControl::CopyToImage(CGrabResultPtr pInBuffer, QImage &OutImage)
{
  uchar* buff = (uchar*)pInBuffer->GetBuffer();
  int nHeight = pInBuffer->GetHeight();
  int nWidth = pInBuffer->GetWidth();
  if(m_size != QSize(nWidth, nHeight)) {
    m_size = QSize(nWidth, nHeight);
    emit sigSizeChange(m_size);
  }
  QImage imgBuff(buff, nWidth, nHeight, QImage::Format_Indexed8);
  OutImage = imgBuff;
  if(pInBuffer->GetPixelType() == PixelType_Mono8) {
    uchar* pCursor = OutImage.bits();
    if ( OutImage.bytesPerLine() != nWidth ) {
      for ( int y=0; y<nHeight; ++y ) {
        pCursor = OutImage.scanLine( y );
        for ( int x=0; x<nWidth; ++x ) {
          *pCursor =* buff;
          ++pCursor;
          ++buff;
        }
      }
    } else {
      memcpy( OutImage.bits(), buff, nWidth * nHeight );
    }
  }
}
 
void SBaslerCameraControl::onTimerGrabImage()
{
  if(m_isOpenAcquire) {
    QImage image;
    GrabImage(image, 5);
    if(!image.isNull()) {
      emit sigCurrentImage(image);
    }
    QTimer::singleShot(5, this, SLOT(onTimerGrabImage()));
  }
}
 
int SBaslerCameraControl::OpenCamera(QString cameraSN)
{
  try {
    CDeviceInfo cInfo;
    String_t str = String_t(cameraSN.toStdString().c_str());
    cInfo.SetSerialNumber(str);
    m_basler.Attach(CTlFactory::GetInstance().CreateDevice(cInfo));
    m_basler.Open();
    //获取触发模式
    getFeatureTriggerSourceType();
    m_isOpen = true;
  } catch (GenICam::GenericException &e) {
    OutputDebugString(L"OpenCamera Error\n");
    m_isOpen = false;
    return -2;
  }
  return 0;
}
 
int SBaslerCameraControl::CloseCamera()
{
  if(!m_isOpen) {
    return -1;
  }
  try {
    if(m_basler.IsOpen()) {
      m_basler.DetachDevice();
      m_basler.Close();
    }
  } catch (GenICam::GenericException &e) {
    OutputDebugString(LPCWSTR(e.GetDescription()));
    return -2;
  }
  return 0;
}
 
void SBaslerCameraControl::setExposureTime(double time)
{
  SetCamera(Type_Basler_ExposureTimeAbs, time);
}
 
int SBaslerCameraControl::getExposureTime()
{
  return QString::number(GetCamera(Type_Basler_ExposureTimeAbs)).toInt();
}
 
int SBaslerCameraControl::getExposureTimeMin()
{
  return DOUBLE_MIN;
}
 
int SBaslerCameraControl::getExposureTimeMax()
{
  return DOUBLE_MAX;
}
 
void SBaslerCameraControl::setFeatureTriggerSourceType(QString type)
{
  //停止采集
  if(m_isOpenAcquire) {
    StopAcquire();
  }
  if(type == "Freerun") {
    SetCamera(Type_Basler_Freerun);
  } else if(type == "Line1"){
    SetCamera(Type_Basler_Line1);
  }
}
 
QString SBaslerCameraControl::getFeatureTriggerSourceType()
{
  INodeMap &cameraNodeMap = m_basler.GetNodeMap();
  CEnumerationPtr ptrTriggerSel = cameraNodeMap.GetNode ("TriggerSelector");
  ptrTriggerSel->FromString("FrameStart");
  CEnumerationPtr ptrTrigger = cameraNodeMap.GetNode ("TriggerMode");
  ptrTrigger->SetIntValue(1);
  CEnumerationPtr ptrTriggerSource = cameraNodeMap.GetNode ("TriggerSource");
 
  String_t str = ptrTriggerSource->ToString();
  m_currentMode = QString::fromLocal8Bit(str.c_str());
  return m_currentMode;
}
 
void SBaslerCameraControl::setFeatureTriggerModeType(bool on)
{
  INodeMap &cameraNodeMap = m_basler.GetNodeMap();
  CEnumerationPtr ptrTriggerSel = cameraNodeMap.GetNode ("TriggerSelector");
  ptrTriggerSel->FromString("FrameStart");
  CEnumerationPtr ptrTrigger = cameraNodeMap.GetNode ("TriggerMode");
  ptrTrigger->SetIntValue(on?1:0);
}
 
bool SBaslerCameraControl::getFeatureTriggerModeType()
{
  INodeMap &cameraNodeMap = m_basler.GetNodeMap();
  CEnumerationPtr ptrTriggerSel = cameraNodeMap.GetNode ("TriggerSelector");
  ptrTriggerSel->FromString("FrameStart");
  CEnumerationPtr ptrTrigger = cameraNodeMap.GetNode ("TriggerMode");
  return ptrTrigger->GetIntValue() == 1;
}
 
void SBaslerCameraControl::SetCamera(SBaslerCameraControl::SBaslerCameraControl_Type index, double tmpValue)
{
  INodeMap &cameraNodeMap = m_basler.GetNodeMap();
  switch (index) {
  case Type_Basler_Freerun: {
    CEnumerationPtr ptrTriggerSel = cameraNodeMap.GetNode ("TriggerSelector");
    ptrTriggerSel->FromString("FrameStart");
    CEnumerationPtr ptrTrigger = cameraNodeMap.GetNode ("TriggerMode");
#ifdef Real_Freerun
    ptrTrigger->SetIntValue(0);
#else //Software
    ptrTrigger->SetIntValue(1);
    CEnumerationPtr ptrTriggerSource = cameraNodeMap.GetNode ("TriggerSource");
    ptrTriggerSource->FromString("Software");
#endif
  } break;
  case Type_Basler_Line1: {
    CEnumerationPtr ptrTriggerSel = cameraNodeMap.GetNode ("TriggerSelector");
    ptrTriggerSel->FromString("FrameStart");
    CEnumerationPtr ptrTrigger = cameraNodeMap.GetNode ("TriggerMode");
    ptrTrigger->SetIntValue(1);
    CEnumerationPtr ptrTriggerSource = cameraNodeMap.GetNode ("TriggerSource");
    ptrTriggerSource->FromString("Line1");
  } break;
  case Type_Basler_ExposureTimeAbs: {
    const CFloatPtr exposureTime = cameraNodeMap.GetNode("ExposureTimeAbs");
    exposureTime->SetValue(tmpValue);
  } break;
  case Type_Basler_GainRaw: {
    const CIntegerPtr cameraGen = cameraNodeMap.GetNode("GainRaw");
    cameraGen->SetValue(tmpValue);
  } break;
  case Type_Basler_AcquisitionFrameRateAbs: {
    const CBooleanPtr frameRate = cameraNodeMap.GetNode("AcquisitionFrameRateEnable");
    frameRate->SetValue(TRUE);
    const CFloatPtr frameRateABS = cameraNodeMap.GetNode("AcquisitionFrameRateAbs");
    frameRateABS->SetValue(tmpValue);
  } break;
  case Type_Basler_Width: {
    const CIntegerPtr widthPic = cameraNodeMap.GetNode("Width");
    widthPic->SetValue(tmpValue);
  } break;
  case Type_Basler_Height: {
    const CIntegerPtr heightPic = cameraNodeMap.GetNode("Height");
    heightPic->SetValue(tmpValue);
  } break;
  case Type_Basler_LineSource: {
    CEnumerationPtr ptrLineSource = cameraNodeMap.GetNode ("LineSource");
    ptrLineSource->SetIntValue(2);
  } break;
  default:
    break;
  }
}
 
double SBaslerCameraControl::GetCamera(SBaslerCameraControl::SBaslerCameraControl_Type index)
{
  INodeMap &cameraNodeMap = m_basler.GetNodeMap();
  switch (index) {
  case Type_Basler_ExposureTimeAbs: {
    const CFloatPtr exposureTime = cameraNodeMap.GetNode("ExposureTimeAbs");
    return exposureTime->GetValue();
  } break;
  case Type_Basler_GainRaw: {
    const CIntegerPtr cameraGen = cameraNodeMap.GetNode("GainRaw");
    return cameraGen->GetValue();
  } break;
  case Type_Basler_AcquisitionFrameRateAbs: {
    const CBooleanPtr frameRate = cameraNodeMap.GetNode("AcquisitionFrameRateEnable");
    frameRate->SetValue(TRUE);
    const CFloatPtr frameRateABS = cameraNodeMap.GetNode("AcquisitionFrameRateAbs");
    return frameRateABS->GetValue();
  } break;
  case Type_Basler_Width: {
    const CIntegerPtr widthPic = cameraNodeMap.GetNode("Width");
    return widthPic->GetValue();
  } break;
  case Type_Basler_Height: {
    const CIntegerPtr heightPic = cameraNodeMap.GetNode("Height");
    return heightPic->GetValue();
  } break;
  default:
    return -1;
    break;
  }
}
 
long SBaslerCameraControl::StartAcquire()
{
  m_isOpenAcquire = true;
  qDebug() << "SBaslerCameraControl IsGrabbing";
  try {
    qDebug() << "SBaslerCameraControl StartAcquire" << m_currentMode;
     if(m_currentMode == "Freerun") {
       m_basler.StartGrabbing(GrabStrategy_LatestImageOnly,GrabLoop_ProvidedByInstantCamera);
     } else if(m_currentMode == "Software") {
       m_basler.StartGrabbing(GrabStrategy_LatestImageOnly);
       onTimerGrabImage();
     } else if(m_currentMode == "Line1") {
       m_basler.StartGrabbing(GrabStrategy_OneByOne);
     } else if(m_currentMode == "Line2") {
       m_basler.StartGrabbing(GrabStrategy_OneByOne);
     }
  } catch (GenICam::GenericException &e) {
    OutputDebugString(L"StartAcquire error:");
    return -2;
  }
  return 0;
}
 
long SBaslerCameraControl::StopAcquire()
{
  m_isOpenAcquire = false;
  qDebug() << "SBaslerCameraControl StopAcquire";
  try {
    if (m_basler.IsGrabbing()) {
      m_basler.StopGrabbing();
    }
  } catch (GenICam::GenericException &e) {
    OutputDebugString(LPCWSTR(e.GetDescription()));
    return -2;
  }
  return 0;
}
 
long SBaslerCameraControl::GrabImage(QImage &image, int timeout)
{
  try {
    if (!m_basler.IsGrabbing()) {
      StartAcquire();
    }
    CGrabResultPtr ptrGrabResult;
    if(m_currentMode == "Freerun") {
    } else if(m_currentMode == "Software") {
      if (m_basler.WaitForFrameTriggerReady(1000, TimeoutHandling_Return)) {
        m_basler.ExecuteSoftwareTrigger();
        m_basler.RetrieveResult(timeout, ptrGrabResult,TimeoutHandling_Return);
      }
    } else if(m_currentMode == "Line1") {
      m_basler.RetrieveResult(timeout, ptrGrabResult, TimeoutHandling_Return);
    } else if(m_currentMode == "Line2") {
      m_basler.RetrieveResult(timeout, ptrGrabResult, TimeoutHandling_Return);
    }
    if (ptrGrabResult->GrabSucceeded()) {
      if (!ptrGrabResult.IsValid()) { OutputDebugString(L"GrabResult not Valid Error\n"); return -1; }
      EPixelType pixelType = ptrGrabResult->GetPixelType();
      switch (pixelType) {
      case PixelType_Mono8: {
        CopyToImage(ptrGrabResult, image);
      } break;
      case PixelType_BayerRG8: { qDebug() << "what: PixelType_BayerRG8"; } break;
      default: qDebug() << "what: default"; break;
      }
    } else {
      OutputDebugString(L"Grab Error!!!");
      return -3;
    }
  } catch (GenICam::GenericException &e) {
    OutputDebugString(L"GrabImage Error\n");
    return -2;
  } catch(...) {
    OutputDebugString(L"ZP 11 Shot GetParam Try 12 No know Error\n");
    return -1;
  }
  return 0;
}

如何调用

源文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QDebug>
 
MainWindow::MainWindow(QWidget *parent) :
  QMainWindow(parent),
  ui(new Ui::MainWindow)
{
  ui->setupUi(this);
  m_control = new SBaslerCameraControl(this);
  m_control->initSome();
  connect(m_control, &SBaslerCameraControl::sigCurrentImage, [=](QImage img){
    QPixmap pix = QPixmap::fromImage(img).transformed(m_matrix);
    ui->label->setPixmap(pix);
    ui->widget_pic->setFixedSize(pix.size());
  });
  connect(m_control, &SBaslerCameraControl::sigSizeChange, [=](QSize size){
    // 默认大小641,494
    ui->label_size->setText(QString("\345\260\272\345\257\270:%0*%1").arg(QString::number(size.width())).arg(QString::number(size.height()))); // 尺寸
    ui->widget_pic->setFixedSize(size);
  });
  m_control->OpenCamera(m_control->cameras().first());
}
 
MainWindow::~MainWindow()
{
  m_control->CloseCamera();
  m_control->deleteAll();
  delete ui;
}
 
void MainWindow::on_pushButton_GetExTime_clicked()
{
  ui->label_exTime->setText(QString::number(m_control->getExposureTime()));
}
 
void MainWindow::on_pushButton_SetExTime_clicked()
{
  m_control->setExposureTime(ui->lineEdit_exTime->text().toDouble());
}
 
void MainWindow::on_pushButton_SetMode_clicked()
{
  m_control->setFeatureTriggerSourceType(ui->lineEdit_SetMode->text());
}
 
void MainWindow::on_pushButton_GetMode_clicked()
{
  ui->label_Mode->setText(m_control->getFeatureTriggerSourceType());
}
 
void MainWindow::on_pushButton_CFMode_clicked()
{
  ui->label_CFMode->setText(m_control->getFeatureTriggerModeType()?"Open":"Close");
}
 
void MainWindow::on_comboBox_CFMode_activated(int index)
{
  m_control->setFeatureTriggerModeType(index == 0);
}
 
void MainWindow::on_pushButton_Start_clicked()
{
  if(ui->pushButton_Start->text() == "\345\274\200\345\247\213\351\207\207\351\233\206") {// 开始采集
    m_control->StartAcquire();
    ui->pushButton_Start->setText("\347\273\223\346\235\237\351\207\207\351\233\206");// 结束采集
  } else {
    m_control->StopAcquire();
    ui->pushButton_Start->setText("\345\274\200\345\247\213\351\207\207\351\233\206");// 开始采集
  }
}
 
void MainWindow::on_pushButtonRotate_clicked()
{
  m_matrix.rotate(90);
}

pro文件

(注意:引用库文件的路径哦)

我把源码已经上传到码云和Github

码云

Github


版权声明 : 本文内容来源于互联网或用户自行发布贡献,该文观点仅代表原作者本人。本站仅提供信息存储空间服务和不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权, 违法违规的内容, 请发送邮件至2530232025#qq.cn(#换@)举报,一经查实,本站将立刻删除。
原文链接 : https://blog.csdn.net/u014597198/article/details/78844664
相关文章
  • WPF实现窗体亚克力效果的代码

    WPF实现窗体亚克力效果的代码
    WPF 窗体设置亚克力效果 框架使用大于等于.NET40。 Visual Studio 2022。 项目使用MIT开源许可协议。 WindowAcrylicBlur设置亚克力颜色。 Opacity设置透
  • C#非托管泄漏中HEAP_ENTRY的Size对不上解析

    C#非托管泄漏中HEAP_ENTRY的Size对不上解析
    一:背景 1. 讲故事 前段时间有位朋友在分析他的非托管泄漏时,发现NT堆的_HEAP_ENTRY的 Size 和!heap命令中的 Size 对不上,来咨询是怎么回事?
  • C#中ArrayList 类的使用介绍
    一:ArrayList 类简单说明 动态数组ArrayList类在System.Collecions的命名空间下,所以使用时要加入System.Collecions命名空间,而且ArrayList提供添加,
  • C#使用BinaryFormatter类、ISerializable接口、XmlSeriali

    C#使用BinaryFormatter类、ISerializable接口、XmlSeriali
    序列化是将对象转换成字节流的过程,反序列化是把字节流转换成对象的过程。对象一旦被序列化,就可以把对象状态保存到硬盘的某个位
  • C#序列化与反序列化集合对象并进行版本控制
    当涉及到跨进程甚至是跨域传输数据的时候,我们需要把对象序列化和反序列化。 首先可以使用Serializable特性。 1 2 3 4 5 6 7 8 9 10 11 12 13 14
  • C#事件中关于sender的用法解读

    C#事件中关于sender的用法解读
    C#事件sender的小用法 开WPF新坑了,看了WPF的炫酷界面,再看看winForm实在是有些惨不忍睹(逃)。后面会开始写一些短的学习笔记。 一、什么
  • 在C#程序中注入恶意DLL的方法

    在C#程序中注入恶意DLL的方法
    一、背景 前段时间在训练营上课的时候就有朋友提到一个问题,为什么 Windbg 附加到 C# 程序后,程序就处于中断状态了?它到底是如何实现
  • 基于C#实现一个简单的FTP操作工具
    实现功能 实现使用FTP上传、下载、重命名、刷新、删除功能 开发环境 开发工具: Visual Studio 2013 .NET Framework版本:4.5 实现代码 1 2 3 4 5 6 7
  • C#仿QQ实现简单的截图功能

    C#仿QQ实现简单的截图功能
    接上一篇写的截取电脑屏幕,我们在原来的基础上加一个选择区域的功能,实现自定义选择截图。 个人比较懒,上一篇的代码就不重新设计
  • C#实现线性查找算法的介绍
    线性查找,肯定是以线性的方式,在集合或数组中查找某个元素。 通过代码来理解线性查找 什么叫线性?还是在代码中体会吧。 首先需要一
  • 本站所有内容来源于互联网或用户自行发布,本站仅提供信息存储空间服务,不拥有版权,不承担法律责任。如有侵犯您的权益,请您联系站长处理!
  • Copyright © 2017-2022 F11.CN All Rights Reserved. F11站长开发者网 版权所有 | 苏ICP备2022031554号-1 | 51LA统计