点点滴滴 访问量:
posts - 84,comments - 114,trackbacks - 5


typedef struct {
    VarBind * list;    
    int  len;     
} VarBindList;
 
//winapi函数原型:
int SnmpMgrRequest(
    IN     void*  session,         
    IN     BYTE               requestType,      
    IN OUT VarBindList   *variableBindings,
       OUT long *errorStatus,     
       OUT long *errorIndex       
    );
 
//c#中的声明:
[DllImport("mgmtapi.dll", EntryPoint = "SnmpMgrRequest", SetLastError = true,
   CharSet = CharSet.Ansi,ExactSpelling = true, CallingConvention = CallingConvention.StdCall)]
public static extern bool SnmpMgrRequest(
   string Session,
   Byte RequestType,
   ref VarBindList variableBindings,
   ref long errorStatus,
   ref long errorIndex
);

 

问题:
1. 该声明是否正确?
2. 输入参数VarBindList 该怎么封装。
 
望广大高手多多指导

posted @ 2007-12-18 15:58 sopper 阅读(128) | 评论 (0)编辑
 

版本为20.49.30的瑞星软件与vc6有冲突,造成的问题是vc6不能正常编译,vc6错误提示为:




解决办法:

1.取消瑞星的开机自运行功能,并且不要运行瑞星

2.更新瑞星为其他版本

到现在为止笔者还没有发现瑞星与其它软件的冲突现象。

posted @ 2008-06-24 11:29 sopper 阅读(112) | 评论 (1)编辑

 

MFC采用了独特的DDXDDV技术。

DDX将数据成员变量同对话类模板内的控件相连接,这样就使得数据在控件之间很容易地传输。

DDV用于数据的校验,例如它能自动校验数据成员变量数值的范围,并发出相应的警告。

 

在类向导下添加成员变量的过程很简单,需要说明的是

。在DDVDDX技术中,允许用户为同一个控件关联多个数据成员变量,但必须保证这些变量名是互不相同的,且这些变量在同一个类型不能有多个变量,即在ValueControl类型中各自只能有一个成员变量。

。如果添加的成员变量是一个数值类型,则在类向导对话框的Member Variables页面正文还要求用户输入变量的范围,这就是控件的数据校验设置。

 

添加完成成员变量后,类向导会在代码文件里加入如下代码

1.          在头文件中,添加与控件关联的成员变量的声明,代码:
// Dialog Data

     //{{AFX_DATA(CMyDlg)

       enum { IDD = IDD_DIALOG5 };

       int          m_edit;

       //}}AFX_DATA

2.          .CPP文件中的类构造函数实现代码处,添加数据成员变量的一些初始化代码

CMyDlg::CMyDlg(CWnd* pParent /*=NULL*/)

         : CDialog(CMyDlg::IDD, pParent)

{

   //{{AFX_DATA_INIT(CMyDlg)

   m_edit = 0;

   //}}AFX_DATA_INIT

}

3.          .CPP文件中的DoDataExchange函数体内,添加控件的DDXDDV代码,它们都是一些以DDV_DDX_开关的函数调用。
void CMyDlg::DoDataExchange(CDataExchange* pDX)

{

      CDialog::DoDataExchange(pDX);//调用此函数作为DDX的开始

      //{{AFX_DATA_MAP(CMyDlg)

      DDX_Text(pDX, IDC_EDIT1, m_edit);//将控件与变量进行数据交换

      DDV_MinMaxInt(pDX, m_edit, 1, 10);//校验最大值和最小值  

      //}}AFX_DATA_MAP

}
需要说明的是,上述代码中以 “//{{AFX_DATA” 或“//{{AFX_DATA_XXXX”开头,而以 “//}}AFX_DATA” 或 “//}}AFX_DATA_”结尾的标记是类向导定义的专门用来做DDX/DDVr 标记,表示该部分的代码是同类向导自动管理,用户一般不需要去更改。

4.          当为一个控件定义一个关联的数据成员变量后,就可以使用CWnd::UpdataData函数实现控件的控制,包括控件相关数据的输入和读取。
UpdateData
FALSE)   数据由控件相关的成员变量向控件传输
UpdateData
TRUE)或参数为空  数据从控件向相关联的成员变量复制

posted @ 2008-05-26 10:49 sopper 阅读(23) | 评论 (0)编辑
 

1.在窗体头文件(如:MyDlg.h)中声明消息处理函数OnButton1                         

protected:

      // Generated message map functions

      //{{AFX_MSG(CMyDlg)

      afx_msg void OnButton1();

      //}}AFX_MSG

2.MyDlg.cpp源文件开头部分的消息映射入口,添加相应的消息映射宏:                 
  
这段代码,表明消息及其处理函数之间的联系。当用户单击按钮控件IDC_BUTTON1 时,
  系统将自动调用
OnButton1函数。

BEGIN_MESSAGE_MAP(CMyDlg, CDialog)

      //{{AFX_MSG_MAP(CMyDlg)

      ON_BN_CLICKED(IDC_BUTTON1, OnButton1)

      //}}AFX_MSG_MAP

END_MESSAGE_MAP()

3.MyDlg.cpp文件中写入一个空的消息处理函数的模板,以便用户填入具体代码,如下面的框架:

      void CMyDlg::OnButton1()

{

      // TODO: Add your control notification handler code here

     

}

在消息映射函数体框架中用户可以添加一些代码,例如:

      void CMyDlg::OnButton1()

{

      // TODO: Add your control notification handler code here

      MessageBox(“消息映射机制!”);

}

posted @ 2008-05-22 17:28 sopper 阅读(23) | 评论 (0)编辑
 

摘之:《高质量C++/C编程指南》

       发生内存错误是件非常麻烦的事情。编译器不能自动发现这些错误,通常是在程序运行时才能捕捉到。而这些错误大多没有明显的症状,时隐时现,增加了改错的难度。有时用户怒气冲冲地把你找来,程序却没有发生任何问题,你一走,错误又发作了。

常见的内存错误:

u       内存分配未成功,却使用了它。

编程新手常犯这种错误,因为他们没有意识到内存分配会不成功。常用解决办法是,在使用内存之前检查指针是否为NULL。如果指针p是函数的参数,那么在函数的入口处用assert(p!=NULL)进行检查。如果是用malloc或new来申请内存,应该用if(p==NULL) 或if(p!=NULL)进行防错处理。

u       内存分配虽然成功,但是尚未初始化就引用它。

犯这种错误主要有两个起因:一是没有初始化的观念;二是误以为内存的缺省初值全为零,导致引用初值错误(例如数组)。

内存的缺省初值究竟是什么并没有统一的标准,尽管有些时候为零值,我们宁可信其无不可信其有。所以无论用何种方式创建数组,都别忘了赋初值,即便是赋零值也不可省略,不要嫌麻烦。

u       内存分配成功并且已经初始化,但操作越过了内存的边界。

例如在使用数组时经常发生下标“多1”或者“少1”的操作。特别是在for循环语句中,循环次数很容易搞错,导致数组操作越界。

u       忘记了释放内存,造成内存泄露。

含有这种错误的函数每被调用一次就丢失一块内存。刚开始时系统的内存充足,你看不到错误。终有一次程序突然死掉,系统出现提示:内存耗尽。

动态内存的申请与释放必须配对,程序中mallocfree的使用次数一定要相同,否则肯定有错误(new/delete同理)。

u       释放了内存却继续使用它。

有三种情况:

1)程序中的对象调用关系过于复杂,实在难以搞清楚某个对象究竟是否已经释放了内存,此时应该重新设计数据结构,从根本上解决对象管理的混乱局面。

2)函数的return语句写错了,注意不要返回指向“栈内存”的“指针”或者“引用”,因为该内存在函数体结束时被自动销毁。

3)使用freedelete释放了内存后,没有将指针设置为NULL。导致产生“野指针”。

其对策如下:

l         用malloc或new申请内存之后,应该立即检查指针值是否为NULL。防止使用指针值为NULL的内存。

l         不要忘记为数组和动态内存赋初值。防止将未被初始化的内存作为右值使用。

l         避免数组或指针的下标越界,特别要当心发生“多1”或者“少1”操作。

l         动态内存的申请与释放必须配对,防止内存泄漏。

l         freedelete释放了内存之后,立即将指针设置为NULL,防止产生“野指针”。

posted @ 2008-04-02 17:53 sopper 阅读(123) | 评论 (0)编辑
 

CORBA_TAO系统环境变量的配置,对于能熟练进行系统环境变量配置的同学来说,应该很简单,对于首次进行配置的同学来说可能不是那么容易了。

首先右击“我的电脑”à属性 à高级 à环境变量,然后在环境变量对话框里进行以下操作:

1.新建变量 ACE_ROOT   值设置为CORBA文件夹的路径 比如我的路径是E:"work"ACE_wrappers

2.给变量Path的值加入 %ACE_ROOT%"bin;%ACE_ROOT%"lib

3.新建变量TAO_ROOT     值设置为%ACE_ROOT%"TAO

点击确定保存,ok,环境变量设置完成

接下来在TAO的路径下找到要使用的服务(比如我的路径是E:"work"ACE_wrappers"TAO"orbsvcs"Naming_Service),以文本方式打开run文件,修改IP地址为自己的IP并保存,OK,直接双击运行run,通过。

posted @ 2008-03-29 10:35 sopper 阅读(87) | 评论 (0)编辑

        ManualResetEvent就像一个信号灯,可以利用它的信号,控制当前线程是挂起状态还是运行状态。
        它有几个常用的方法:Reset(),Set(),WaitOne();
        初始化该对象时,可以指定其默认的状态(有信号/无信号);
        在初始化以后,该对象将保持原来的状态不变,直到它的Reset()或者Set()方法被调用;
        Reset()方法将其设置为无信号状态,Set()方法将其设置为有信号状态;
        WaitOne()方法在无信号状态下,可以使当前线程挂起;注意这里说的是当前线程;
        直到调用了Set()方法,该线程才被激活。

        在多线程的代码里,可以使用一个ManualResetEvent对象来控制线程所有线程;
        只要在调用WaitOne()方法前,调用Reset()方法,因为WaitOne()控制的是当前线程;
        但是这样做,ManualResetEvent对象的管理逻辑会变得复杂;
        所以这里建议一条线程一个ManualResetEvent对象。
 

using System;
using System.Collections.Generic;
using System.Text;
using System.Threading;

namespace ConsoleThread
{
    
class ThreadClass
    
{
        
public void threadFun()
        
{
            Thread.Sleep(
1000);
            Console.WriteLine(
"ThreadClass.threadFun 1");

            
//激活被挂起的线程
            Program.allDone.Set();

            Console.WriteLine(
"ThreadClass.threadFun 2");

            
//设置为无信号,如果注释这条语句,
            
//下面的WaitOne()方法就不起做用了
            Program.allDone.Reset();

            
//使当前线程挂起
            Program.allDone.WaitOne();

            Console.WriteLine(
"ThreadClass.threadFun 3");

        }


    }
;
    


    
class Program
    
{
        
public static ManualResetEvent allDone = new ManualResetEvent(false);
        
static void Main(string[] args)
        
{
            Console.WriteLine(
"Thread Start/Stop/Join Sample");
            ThreadClass ThreadC 
= new ThreadClass();
            Thread thread 
= new Thread(new ThreadStart(ThreadC.threadFun));
            thread.Start();

            
//挂起当前线程
            allDone.WaitOne();

            Console.WriteLine(
"Main 1");

            
//因为ThreadClass.threadFun方法里调用了Reset()
            
//所以这里的WaitOne()方法会使主线程也挂起
            
//allDone.WaitOne();

            
//使主线程挂起1秒钟,
            
//为了ThreadClass.threadFun方法里的Program.allDone.WaitOne()方法
            
//运行时间在Main()方法的allDone.Set()方法前面
            Thread.Sleep(5000);

            
//设置为有信号
            
//如果没有这条语句,ThreadClass.threadFun方法里最后一条语句就不会运行
            allDone.Set();
            Console.WriteLine(
"Main 2");
        }

    }

}
posted @ 2008-03-18 13:03 sopper 阅读(150) | 评论 (2)编辑
     摘要: 以下是MSDN里异步socket示例的代码,我在代码里加入了显示当前线程ID的语句,想看看异步socket的线程是怎么分配的,与客户端配合运行后的结果如图CodeCode highlighting produced by Actipro CodeHighlighter (freeware)http://www.CodeHighlighter.com/-->Server端代码:usingSyste...  阅读全文
posted @ 2008-03-14 11:46 sopper 阅读(294) | 评论 (6)编辑
 

 C#控制台应用程序下,我们常常看到Main函数带有一个string[] args参数,那么你知道它有什么用处?

步骤1:建立一个控制台应用程序,暂且命名为Main

步骤2:贴上下面这段代码,并生成release版本的exe

       int argsLength = args.Length;

            Console.WriteLine("Main函数参数args的长度:" + argsLength.ToString());

            for (int i = 0; i < argsLength; i++)

            {

                Console.Write("第" + i.ToString() + "位是:");

                Console.WriteLine(args[i].ToString());

            }

步骤3:在release文件下复制Main.exe到C盘的根目录下(随便一个盘符的根目录都可以,只是为了后面使用的方便)

步骤4:在命令行模式下输入c:\>main a b c ,敲回车看结果

输出结果为:

Main函数参数args的长度:3

0位是:a

1位是:b

2位是:c

posted @ 2008-02-23 11:07 sopper 阅读(170) | 评论 (0)编辑
 

今天向朋友请教一个问题,对话是这样子的,

问:c#下用一个实例 赋给一个新定义的对象,copy过去?还是引用?

答:引用

问:你肯定?

答: 恩,C#下的赋值都是引用

完了我就写了下面的代码去测试,代码如下:

class myClass
    
{
        
public int num ;
    }
;

    
struct myStruct
    
{
        
public int num ;
    }
;

class Program
    
{
        
static void Main(string[] args)
        
{
          myClass myclass 
= new myClass();
          myClass myclassb 
= myclass;

          myClass myclassa 
= new myClass();
          myclassa 
= myclass;  

          myclassa.num 
= 1;
          Console.WriteLine(
"myclass.num = " + myclass.num.ToString());
          Console.WriteLine(
"myclassa.num =" + myclassa.num.ToString() + "\t\tmyclassb.num = " + myclassb.num.ToString()); 


          myclass.num 
= 2;
          Console.WriteLine(
"myclass.num = " + myclass.num.ToString());
          Console.WriteLine(
"myclassa.num =" + myclassa.num.ToString() + "\t\tmyclassb.num = " + myclassb.num.ToString()); 


///////////////////////////////////////////////////////////////////// 
          myStruct mystruct = new myStruct();
          myStruct mystruct1 
= mystruct;
          mystruct1.num 
= 1;
          Console.WriteLine(
"\n\nmystruct.num =" + mystruct.num.ToString() + "\t\tmystruct1.num =" + mystruct1.num.ToString());

          mystruct.num 
= 2;
          Console.WriteLine(
"mystruct.num =" + mystruct.num.ToString() + "\t\tmystruct1.num =" + mystruct1.num.ToString());
        }

    }



 

代码看完了,写出你认为的结果,是什么?





































 

我想不用说大家都知道结论是什么了吧  *^_^*



posted @ 2008-01-09 19:15 sopper 阅读(170) | 评论 (3)编辑
 

在写代码时都习惯了这样的写法

Int num 10;

If(num == 1){……}

类似这样的语句,那么这类语句看起来没错,运行也没错,却是个隐患,因为,如果一旦不小心写成ifnum=1)这个样子,编译时编译器会把它当做一个赋值语句,所以不会报任何错误,在小程序里这样子的错误是很容易找出来,如果出现在一个大项目里,那么想找出这样一个错误,那可不会很容易了。

那么怎么避免这样的错误发生呢?也很简单,把常量写在前面

Int num=10

If(1 == num)

{……}

如果不小心写成了if1=num)这个样子,编译时直接就会报错。是不是很省心?

posted @ 2008-01-03 17:43 sopper 阅读(356) | 评论 (13)编辑