Posts Tagged ‘C++’

C++ struct虚拟类(接口)使用范例

星期二, 六月 18th, 2013 10 views

首先是接口的编写
InterfaceTest.h

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#pragma once
/************************************************************************/
/* 接口定义                                                             */
/************************************************************************/
struct ITestInterface
{
    virtual ~ITestInterface(){}
    virtual void Release() = 0;//释放接口
    virtual void TestFun() = 0;//接口函数示例

};
extern"C"
{
    ITestInterface* CreateInterface();//创建接口
};

接下来新建一个类实现这个接口:
CTest.h

1
2
3
4
5
6
7
8
9
10
11
#pragma once
#include "InterfaceTest.h"
/************************************************************************/
/* 接口实现                                                             */
/************************************************************************/
class CTest : public ITestInterface
{
public:
    virtual void Release();
    virtual void TestFun();
};

CTest.cpp

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
#include "CTest.h"

ITestInterface* CreateInterface()
{
    return new CTest;
}
void CTest::Release()
{
    delete this;
}

void CTest::TestFun()
{
    //这里实现接口功能
}

接下来是该接口类的使用方法

Main.cpp

1
2
3
4
5
6
7
8
#include "InterfaceTest.h"

void main()
{
    ITestInterface* test= CreateInterface();//创建接口
    test->TestFun();//执行接口函数
    test->Release();//释放接口
}

代码即讲解,最后感谢一下FG提供的方案。
本文到此,谢谢关注。

BeiTown
2013.06.18

C++在windows下创建线程范例

星期一, 六月 17th, 2013 16 views

虽然简单,但依旧记录一下,接触和使用的语言太多,长时间不用这门语言就容易遗忘,仅当日记吧。

在windows下,常常使用SDK win32 api来编写多线程的程序,实现方法如下

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#include <windows.h>

//Fun为自定义的线程函数
DWORD  WINAPI  Fun( LPVOID  lpParamter )
{
    while(1) {

        printf("新线程正在执行...");

    }
}

int main()
{
    HANDLE  hThread = CreateThread(NULL, 0, Fun, NULL, 0, NULL);//创建线程
    return 0;
}

以上为最简实现方法。

其他拓展后续添加。

本文到此,谢谢关注。

 

BeiTown

2013.06.17

QT 多线程(UI线程)间的signal/slot(信号与槽)通信

星期三, 五月 1st, 2013 184 views

写这篇的时候感觉有点像写之前Android主线程与子线程间的通信消息队列,其实需要这么做的原因基本相同,即QT在主线程(UI线程)中某些阻塞行为会造成UI的更新的阻塞,举例来说,在UI线程中创建一个while循环,并在这个while循环中对UI进行更新,运行结果是UI完全无响应,因为UI线程一直卡在while中无法跳出来去完成更新,虽然它不断的得到了更新UI的通知。

因此在本篇中我们将通过多线程的方式来解决此类问题。

QT中已经替我们实现了一个线程类QThread,我们只需要继承它就好。使用时只需->start()即可。

1
2
3
4
5
6
7
8
9
10
class MyThread : public QThread
{
Q_OBJECT
public:
    MyThread();
signals://定义一个信号
    void sendString(QString);
protected:
    void run();
};

上面的代码简单实现了一个线程类的头文件,这里注意一下定义的signals(信号)。
信号与槽是QT特有的一个通信机制,简单阐述一下其运用在线程间的工作流程。
(更多…)

C++网络安全工具编程(一)connect端口扫描器

星期日, 四月 28th, 2013 38 views

端口扫描的种类有很多,其中最简单的即为基于TCP三次握手协议的connect扫描器。其原理为与服务端口建立一个socket连接,当连接上时即可判断端口打开,之后断开连接,进行下一端口的试探。

首先来看一个最简的c++客户端与目标服务器建立socket连接的基础代码

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
#include "stdafx.h"
#include <string .h>
#include <winsock .h>
#include <iostream>
#pragma comment(lib,"ws2_32.lib")
using namespace std;
int _tmain(int argc, _TCHAR* argv[])
{
    //初始化Windows Sockets 动态库

    WSADATA wsaData;
    if(WSAStartup(MAKEWORD(2,2),&wsaData)!=0)
    {
        cout< <"找不到可使用的WinSock dll!"<<endl;
        return 1;
    }

    //创建套接字
    SOCKET sClient=socket(AF_INET,SOCK_STREAM,IPPROTO_TCP);
    if(sClient==INVALID_SOCKET)
    {
        cout<<"创建客户端socket失败!"<<endl;
        return 1;
    }
    //连接服务器
    SOCKADDR_IN addrServ;
    addrServ.sin_family=AF_INET;
    addrServ.sin_addr.S_un.S_addr=inet_addr("127.0.0.1");
    addrServ.sin_port=htons(10046);

    if(connect(sClient,(sockaddr *)&addrServ,sizeof(sockaddr))==SOCKET_ERROR)
    {
        cout<<"连接服务器失败!"<<endl;
        closesocket(sClient);
        return 1;
    }
    else
        cout<<"连接服务器成功!"<<endl;
   
    //关闭套接字,释放资源
    closesocket(sClient);
    WSACleanup();

    return 0;

(更多…)

C++ for Arduino EventTimer(事件定时器)循环队列

星期六, 四月 20th, 2013 167 views

我们知道在Arduino中是没有线程这个概念的,如果需要同时按照时间间隔执行多个事件,使用系统自带的delay()进行阻塞势必会影响到后面的事件。例如在loop()中我们需要不间断的向电机发送脉冲信号使之行走,同时每间隔1s向控制端发送一次数据。如果采用delay(1000)的方法,电机则会每隔1s才获得一次脉冲信号,这不是我们想要的。所以,我们需要为此自定义一个事件定时器。

事件定时器类的C++代码如下:
EventTimer.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
#pragma once
#include "Arduino.h"
typedef void (*LPFUNC)();//typedef定义一个函数指针
class EventTimer
{
public:
    EventTimer(void);
    ~EventTimer(void);
    void Init();//初始化
    void Looper();//事件循环
    void AddEvent(LPFUNC fun,int delay,int repeat);//添加一个事件
   
private:
        /*事件结构体*/
    struct EventNode{
        LPFUNC fun;//事件函数体
        int delay;//执行延时
        int repeat;//执行次数
        int lasttime;//上一个时间
        EventNode * next,* prior;//上一级、下一级指针

    };
    EventNode *head;
    EventNode *tail;
};

(更多…)

QT调用多个UI窗口的方法及error LNK2019修复

星期六, 一月 26th, 2013 794 views

首先是创建一个QT项目,选择QT Gui应用。然后一直下一步。

创建完成后项目结构如下

这个时候点运行,出现一个空的mainwindow界面,这里就不截图了。
(更多…)

C++调用DLL的方法

星期六, 十二月 15th, 2012 23 views

关于C++调用DLL的方法有几种,这里给出个人认为较简单的一种,做一个简单的代码范例,见代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
//引入wtypes头文件
#include <wtypes.h>

//定义一个函数指针
typedef void (  * TULIPFUNC )(void);

//定义一个函数指针变量
TULIPFUNC FUNC;

int _tmain(int argc, _TCHAR* argv[])
{
    //加载TEST.Dll
    HINSTANCE hinst=::LoadLibrary("TEST.dll");  

    //找到Dll的TESTFUNC函数
    FUNC=(TULIPFUNC )GetProcAddress(hinst,"TESTFUNC");

    //调用TESTFUNC函数
    FUNC();
}

欢迎补充及交流

BeiTown
2012.12.15

C++获取硬盘信息(序列号)源码

星期五, 十二月 14th, 2012 135 views

代码是老外的,项目中需要用到所以临时找了很多版本,这是目前测试可用性最高的版本,所有代码都写进了一个CPP里
代码有点长,限于篇幅只传一部分吧,其他后面给压缩包。此处为获取硬盘信息的入口函数,感兴趣的朋友可以试着剥离出来

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
long getHardDriveComputerID ()
{
    int done = FALSE;
    // char string [1024];
    __int64 id = 0;
    OSVERSIONINFO version;

    strcpy (HardDriveSerialNumber, "");

    memset (&version, 0, sizeof (version));
    version.dwOSVersionInfoSize = sizeof (OSVERSIONINFO);
    GetVersionEx (&version);
    if (version.dwPlatformId == VER_PLATFORM_WIN32_NT)
    {
        //  this works under WinNT4 or Win2K if you have admin rights
#ifdef PRINTING_TO_CONSOLE_ALLOWED
        printf ("\nTrying to read the drive IDs using physical access with admin rights\n");
#endif
        done = ReadPhysicalDriveInNTWithAdminRights ();

        //  this should work in WinNT or Win2K if previous did not work
        //  this is kind of a backdoor via the SCSI mini port driver into
        //     the IDE drives
#ifdef PRINTING_TO_CONSOLE_ALLOWED
        printf ("\nTrying to read the drive IDs using the SCSI back door\n");
#endif
        // if ( ! done)
        done = ReadIdeDriveAsScsiDriveInNT ();

        //  this works under WinNT4 or Win2K or WinXP if you have any rights
#ifdef PRINTING_TO_CONSOLE_ALLOWED
        printf ("\nTrying to read the drive IDs using physical access with zero rights\n");
#endif
        //if ( ! done)
        done = ReadPhysicalDriveInNTWithZeroRights ();

        //  this works under WinNT4 or Win2K or WinXP or Windows Server 2003 or Vista if you have any rights
#ifdef PRINTING_TO_CONSOLE_ALLOWED
        printf ("\nTrying to read the drive IDs using Smart\n");
#endif
        //if ( ! done)
        done = ReadPhysicalDriveInNTUsingSmart ();
    }
    else
    {
        //  this works under Win9X and calls a VXD
        int attempt = 0;

        //  try this up to 10 times to get a hard drive serial number
        for (attempt = 0;
            attempt < 10 && ! done && 0 == HardDriveSerialNumber [0];
            attempt++)
            done = ReadDrivePortsInWin9X ();
    }

    if (HardDriveSerialNumber [0] > 0)
    {
        char *p = HardDriveSerialNumber;

        WriteConstantString ("HardDriveSerialNumber", HardDriveSerialNumber);

        //  ignore first 5 characters from western digital hard drives if
        //  the first four characters are WD-W
        if ( ! strncmp (HardDriveSerialNumber, "WD-W", 4))
            p += 5;
        for ( ; p && *p; p++)
        {
            if ('-' == *p)
                continue;
            id *= 10;
            switch (*p)
            {
            case '0': id += 0; break;
            case '1': id += 1; break;
            case '2': id += 2; break;
            case '3': id += 3; break;
            case '4': id += 4; break;
            case '5': id += 5; break;
            case '6': id += 6; break;
            case '7': id += 7; break;
            case '8': id += 8; break;
            case '9': id += 9; break;
            case 'a': case 'A': id += 10; break;
            case 'b': case 'B': id += 11; break;
            case 'c': case 'C': id += 12; break;
            case 'd': case 'D': id += 13; break;
            case 'e': case 'E': id += 14; break;
            case 'f': case 'F': id += 15; break;
            case 'g': case 'G': id += 16; break;
            case 'h': case 'H': id += 17; break;
            case 'i': case 'I': id += 18; break;
            case 'j': case 'J': id += 19; break;
            case 'k': case 'K': id += 20; break;
            case 'l': case 'L': id += 21; break;
            case 'm': case 'M': id += 22; break;
            case 'n': case 'N': id += 23; break;
            case 'o': case 'O': id += 24; break;
            case 'p': case 'P': id += 25; break;
            case 'q': case 'Q': id += 26; break;
            case 'r': case 'R': id += 27; break;
            case 's': case 'S': id += 28; break;
            case 't': case 'T': id += 29; break;
            case 'u': case 'U': id += 30; break;
            case 'v': case 'V': id += 31; break;
            case 'w': case 'W': id += 32; break;
            case 'x': case 'X': id += 33; break;
            case 'y': case 'Y': id += 34; break;
            case 'z': case 'Z': id += 35; break;
            }                            
        }
    }

    id %= 100000000;
    if (strstr (HardDriveModelNumber, "IBM-"))
        id += 300000000;
    else if (strstr (HardDriveModelNumber, "MAXTOR") ||
        strstr (HardDriveModelNumber, "Maxtor"))
        id += 400000000;
    else if (strstr (HardDriveModelNumber, "WDC "))
        id += 500000000;
    else
        id += 600000000;

#ifdef PRINTING_TO_CONSOLE_ALLOWED

    printf ("\nHard Drive Serial Number__________: %s\n",
        HardDriveSerialNumber);
    printf ("\nHard Drive Model Number___________: %s\n",
        HardDriveModelNumber);
    printf ("\nComputer ID_______________________: %I64d\n", id);

#endif

    return (long) id;
}

具体就不分析了,有问题欢迎留言谈论,以下是效果截图

源码下载:
【Diskid32源码及演示下载】

C++在VS中导出DLL动态链接库文件的常规方法

星期三, 十二月 12th, 2012 46 views

①建立项目:
[新建项目]选择Win32控制台应用程序,输入项目名点击确定。
在Win32应用程序向导的应用程序类型中选择DLL,附加选项勾选空项目,如下图,之后点击完成。

②创建头文件,代码如下:

1
2
3
4
5
6
7
8
#ifndef DLLTEST_H
#define DLLTEST_H //防止重复定义
 
#define DECLDIR extern "C" __declspec(dllexport) //宏定义

DECLDIR int Test(int a, int b);  //函数声明

#endif

(更多…)