Pages - Menu

標籤

AWS (1) bash (1) Boost (2) C (2) CMake (2) Concurrency_Programming (3) CPP (37) Database (2) DNS (1) Docker (4) Docker-Compose (1) ELK (1) emacs (4) gcp (1) gdrive (1) git (1) gitbash (2) gitlab (1) kvm (4) Linux (5) MT4 (4) MT5 (4) Multicast (2) MySQL (2) Nijatrader8 (1) OpenCV (1) Python (4) QT5 (1) R (1) rdp (3) screenshot (1) ssh (3) Tabnine (1) TCP (1) TensorFlow (1) Tools (12) Ubuntu_1904 (11) Ubuntu_20_04 (5) UDP (1) VS2010 (1) VS2015 (1) VS2019 (1) WebServer (1) Win10 (1) winmerge (1) WSL (1) xrdp (1)

搜尋此網誌

2020年5月2日星期六

Example to simulate class in C.

Aim

In this example, we simulate the class concept in C. We separate public and private parts in the MsgQ_C.c source file. The message Q is a linked list with 2 mutex locks so that the congestion is reduced.

Source



#include <iostream>
#include <thread>
#include <string.h>
#include <unistd.h>

#include "MsgQ_C.h"
#include "Logger.h"

MsgQ_C* queue = createMsgQ_C();

void thread001Fun()
{
    int i = 0;
    while (true)
    {
        char* string = new char[1024];
        sprintf(string, "number %03d", i++);
        pushMsgQ_C((void**)&string, queue);
        usleep(500000); // sleep 0.5 sec
    }
}

void thread002Fun()
{
    int i = 1000;
    while (true)
    {
        char* string = new char[1024];
        sprintf(string, "number %03d", i++);
        pushMsgQ_C((void**)&string, queue);
        usleep(1000000); // sleep 1 sec
    }
}

int main(int argc, char* argv[])
{
    std::thread thread001(thread001Fun);
    std::thread thread002(thread002Fun);
    while (true)
    {
        char* string;
        getMsgQ_C((void**)&string, queue);
        LOGMSG_MSG_C("%s\n", string);
        delete string;
    }

    freeMsgQ_C(queue);
    return 0;
}

Output

$ ./src/HiddenStruct_C 
20200502_195819_176 [MSG]                      main:    43, 13323,number 1000
20200502_195819_176 [MSG]                      main:    43, 13323,number 000
20200502_195819_676 [MSG]                      main:    43, 13323,number 001
20200502_195820_176 [MSG]                      main:    43, 13323,number 1001

Multicast non stop sending setup. Primary and Secondary server.

Aim

This is an example to show how to use multicast to deliver a "non stop" sending server. This class is supported Linux.

Logic

In this example, we first have 2 servers. There is a way for them to select the primary server and send out the multicast data. On the above picture, Server 2 is the primary.

After several seconds in our example, we will turn off Server 2. They will then select the primary server again. There is a chance for Server 2 to become primary again but mostly Server 1 will take the role faster.

Source



#include <iostream>
#include <string.h>
#include <thread>
#include <chrono>
#include <atomic>

#include "MCastArbitrator.h"
#include "Logger.h"
#include "LinuxThread.h"

// usgae: ./MCastArbitrator

std::string MCastAddress = "225.1.32.28";
short MCastPort = 6000;
std::string SenderIP = "192.168.1.208";
class Sender : public LinuxThread
{
public:
    Sender() { m_running = true; }
    ~Sender() { stopThread(); m_running = false; joinThread(); }

    bool InitComponent(int instance) { m_instance = instance; startThread(); return true; }
    void ChangeStatusForTest() { MCArbi.ChangeStatus(MCastArbitrator::MCArbiStatus::SECONDARY); }
private:
    // override
    void *Main()
    {
        std::vector<char> sendData;

        if (MCArbi.InitComponent(SenderIP, MCastPort, 32, m_instance) == MCastArbitrator::MCArbiStatus::SUCCESS)
        {
            MCArbi.JoinGroup(MCastAddress);
            sendData.resize(4);
            int count = 0;
            while(m_running.load())
            {
                memcpy(&sendData[0], &count, sizeof(int));
                MCastArbitrator::MCArbiStatus retStatus = MCArbi.Send(&sendData[0], sizeof(int));
                if (retStatus == MCastArbitrator::MCArbiStatus::SUCCESS)
                {
                    LOGMSG_MSG("Send success! count: %d instance: %d\n", count, m_instance);
                }
                else
                {
                    // LOGMSG_ERR("Send fail! instance: %d\n", m_instance);
                }
                count++;
                usleep(1000000); // 1 sec
            }
        }
        return NULL;
    }
public:
    int m_instance;
private:
    std::atomic<bool> m_running;
    MCastArbitrator MCArbi;
};
int main(int argc, char *argv[])
{
    Sender *sender001 = new Sender(); sender001->InitComponent(1);
    std::this_thread::sleep_for(std::chrono::seconds(1));
    Sender *sender002 = new Sender(); sender002->InitComponent(2);

    int count = 1;
    int lastDie = 2;
    while (true)
    {
        if (count % 5 == 0)
        {
            if (lastDie == 2)
            {
                sender001->ChangeStatusForTest();
                lastDie = 1;
            }
            else
            {
                sender002->ChangeStatusForTest();
                lastDie = 2;
            }
            count = 0;
        }
        count++;
        std::this_thread::sleep_for(std::chrono::seconds(1));
    }
    return 0;
}

Output

$ ./src/MCastArbitrator 
20200502_183146_131 [MSG]           MCastArbitrator::          SendArbitration:    70,  9136,Start thread
20200502_183146_132 [MSG]           MCastArbitrator::       ReceiveArbitration:   106,  9137,Start thread
20200502_183146_632 [MSG]           MCastArbitrator::SwitchStatus_LongTimeNoUpdate:   211,  9137,IN
20200502_183146_632 [MSG]           MCastArbitrator::              PrintStatus:   174,  9137,Status updated Raise hand
20200502_183146_882 [MSG]           MCastArbitrator::              PrintStatus:   174,  9137,Status updated Primary
20200502_183147_131 [MSG]                    Sender::                     Main:    41,  9135,Send success! count: 1 instance: 1
20200502_183147_132 [MSG]           MCastArbitrator::          SendArbitration:    70,  9139,Start thread
20200502_183147_132 [MSG]           MCastArbitrator::       ReceiveArbitration:   106,  9140,Start thread
20200502_183147_132 [MSG]           MCastArbitrator::              PrintStatus:   174,  9140,Status updated Secondary
20200502_183148_132 [MSG]                    Sender::                     Main:    41,  9135,Send success! count: 2 instance: 1
20200502_183149_132 [MSG]                    Sender::                     Main:    41,  9135,Send success! count: 3 instance: 1
20200502_183150_132 [MSG]                    Sender::                     Main:    41,  9135,Send success! count: 4 instance: 1
20200502_183151_386 [MSG]           MCastArbitrator::SwitchStatus_LongTimeNoUpdate:   211,  9140,IN
20200502_183151_386 [MSG]           MCastArbitrator::              PrintStatus:   174,  9140,Status updated Raise hand
20200502_183151_386 [MSG]           MCastArbitrator::SwitchStatus_LongTimeNoUpdate:   211,  9137,IN
20200502_183151_386 [MSG]           MCastArbitrator::              PrintStatus:   174,  9137,Status updated Raise hand
20200502_183151_634 [MSG]           MCastArbitrator::              PrintStatus:   174,  9137,Status updated Secondary
20200502_183151_634 [MSG]           MCastArbitrator::              PrintStatus:   174,  9140,Status updated Primary
20200502_183152_132 [MSG]                    Sender::                     Main:    41,  9138,Send success! count: 5 instance: 2
20200502_183153_132 [MSG]                    Sender::                     Main:    41,  9138,Send success! count: 6 instance: 2

From the above output example, you can see that the first primary server is instance 1. After a while, we turn off instance 1 and then instance 2 comes up.

2020年5月1日星期五

Multicast sender and receiver example for Linux

Aim

This is an example to show Multicast sender and receiver. This class support on Linux.


Source




#include <iostream>
#include <string.h>
#include <thread>
#include <chrono>

#include "MultiCast.h"
#include "Logger.h"

std::string MCastAddress = "225.1.32.28";
short MCastPort = 6000;
std::string SenderIP = "192.168.1.208";
std::string ReceiverIP = "";
void MCastSender()
{
    std::vector<char> sendData;
    Multicast MCast;

    if (MCast.InitComponent(SenderIP, MCastPort) == Multicast::MCStatus::SUCCESS)
    {
        sendData.resize(4);
        int count = 0;
        while(true)
        {
            memcpy(&sendData[0], &count, sizeof(int));
            Multicast::MCStatus retStatus = MCast.Send(MCastAddress, &sendData[0], sizeof(int));
            if (retStatus == Multicast::MCStatus::SUCCESS)
            {
                LOGMSG_MSG_C("Send success! count: %d\n", count);
            }
            else
            {
                LOGMSG_ERR_C("Send fail!\n");
            }
            count++;
            usleep(1000000); // 1 sec
        }
    }
}
void MCastReceiver()
{
    std::vector<char> receivedData;
    std::string fromAddress;
    short fromPort;
    int byteRecv;
    Multicast MCast;

    if (MCast.InitComponent(ReceiverIP, MCastPort) == Multicast::MCStatus::SUCCESS)
    {
        MCast.JoinGroup(MCastAddress);

        receivedData.resize(1024);
        while(true)
        {
            if (MCast.SelectRead(500, 0) == Multicast::MCStatus::READ) // wait for 500 microsecond
            {
                if (MCast.Recv(receivedData, fromAddress, fromPort, byteRecv) == Multicast::MCStatus::SUCCESS)
                {
                    int count;
                    memcpy(&count, &receivedData[0], sizeof(int));
                    LOGMSG_MSG_C("Received from %s:%u count: %d\n", fromAddress.c_str(), fromPort, count);
                }
            }
        }
    }
}
int main(int argc, char *argv[])
{
    std::thread senderTH(MCastSender);
    senderTH.detach();
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::thread receiverTH(MCastReceiver);
    receiverTH.detach();

    std::this_thread::sleep_for(std::chrono::seconds(5));
    return 0;
}

Output

$ ./src/MCastSenderReceiver 
20200502_123309_832 [MSG]               MCastSender:    28, 25698,Send success! count: 0
20200502_123310_833 [MSG]               MCastSender:    28, 25698,Send success! count: 1
20200502_123311_833 [MSG]               MCastSender:    28, 25698,Send success! count: 2

UDP server client example for Linux

Aim

This is an example to show UDP server and client example. This class support Linux only.


Source



#include <iostream>
#include <string.h>

#include "UDPCast.h"
#include "Logger.h"

std::string serverIP = "192.168.1.208";
std::string clientIP = "192.168.1.208";
short serverPort = 7788;
short clientPort = 8899;
void ServerWorker()
{
    std::vector<char> sendData;
    std::vector<char> recvData;
    UDPCast udpServer;
    if (udpServer.InitComponent(serverIP, serverPort, false) == UDPCast::UDPStatus::SUCCESS)
    {
        int count = 0;
        sendData.resize(4);
        recvData.resize(4);
        while (true)
        {
            std::string clientAddress;
            short clientPort;
            int byteRecv = 0;
            UDPCast::UDPStatus retStatus = udpServer.Recv(clientAddress, clientPort, recvData, byteRecv);
            if (retStatus == UDPCast::UDPStatus::SUCCESS && byteRecv > 0)
            {
                int countRecv = -1;
                memcpy(&countRecv, &recvData[0], sizeof(int));
                LOGMSG_MSG_C("Received count: %d byteRecv: %d\n", countRecv, byteRecv);
            }

            memcpy(&sendData[0], &count, sizeof(int));
            retStatus = udpServer.Send(clientAddress, clientPort, &sendData[0], sizeof(int));
            if (retStatus == UDPCast::UDPStatus::SUCCESS)
            {
                LOGMSG_MSG_C("Send success! count: %d\n", count);
            }
            else
            {
                LOGMSG_ERR_C("Send fail!\n");
            }
            count++;
        }
    }
    else
    {
        LOGMSG_ERR_C("Cannot InitComponent\n");
    }
}
void ClientWorker()
{
    std::vector<char> sendData;
    std::vector<char> recvData;
    UDPCast udpClient;

    if (udpClient.InitComponent(clientIP, clientPort, true) == UDPCast::UDPStatus::SUCCESS)
    {
        sendData.resize(4);
        recvData.resize(4);
        int count = 2000;
        while (true)
        {
            memcpy(&sendData[0], &count, sizeof(int));
            UDPCast::UDPStatus retStatus = udpClient.Send(serverIP, serverPort, &sendData[0], sizeof(int));
            if (retStatus == UDPCast::UDPStatus::SUCCESS)
            {
                LOGMSG_MSG_C("Send success! count: %d\n", count);
            }
            else
            {
                LOGMSG_ERR_C("Send fail!\n");
            }
            count++;

            int byteRecv = 0;
            retStatus = udpClient.Recv(serverIP, serverPort, recvData, byteRecv);
            if (retStatus == UDPCast::UDPStatus::SUCCESS && byteRecv > 0)
            {
                int countRecv;
                memcpy(&countRecv, &recvData[0], sizeof(int));
                LOGMSG_MSG_C("Received count: %d\n", countRecv);
            }
            usleep(1000000); // 1 sec
        }
    }
}
int main(int argc, char *argv[])
{
    std::thread serverTH(ServerWorker);
    serverTH.detach();
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::thread clientTH(ClientWorker);
    clientTH.detach();

    std::this_thread::sleep_for(std::chrono::seconds(5));
    return 0;
}

Output

$ ./src/UDPServerClient 
20200502_112401_921 [MSG]              ClientWorker:    69, 22550,Send success! count: 2000
20200502_112401_921 [MSG]              ServerWorker:    31, 22548,Received count: 2000 byteRecv: 4
20200502_112401_921 [MSG]              ServerWorker:    38, 22548,Send success! count: 0
20200502_112401_921 [MSG]              ClientWorker:    83, 22550,Received count: 0
20200502_112402_921 [MSG]              ClientWorker:    69, 22550,Send success! count: 2001
20200502_112402_921 [MSG]              ServerWorker:    31, 22548,Received count: 2001 byteRecv: 4
20200502_112402_922 [MSG]              ServerWorker:    38, 22548,Send success! count: 1
20200502_112402_922 [MSG]              ClientWorker:    83, 22550,Received count: 1

TCP Server and Client example for Linux

Aim

An example to show how to do TCP communication. Support Linux only now.


Source



#include <iostream>
#include <string.h>
#include <thread>
#include <chrono>

#include "TCPCast.h"
#include "Logger.h"

std::string serverIP = "192.168.1.208";
short serverPort = 7788;
void ServerWorker()
{
    std::vector<char> sendData;
    std::vector<char> recvData;
    TCPCast tcpServer;
    if (tcpServer.InitComponent(serverIP, serverPort, false) == TCPCast::TCPStatus::SUCCESS)
    {
        int count = 0;
        sendData.resize(4);
        recvData.resize(4);
        int clientHandle = tcpServer.Accept(); // waiting for client
        while (true)
        {
            memcpy(&sendData[0], &count, sizeof(int));
            TCPCast::TCPStatus retStatus = tcpServer.ServerSend(clientHandle, &sendData[0], sizeof(int));
            if (retStatus == TCPCast::TCPStatus::SUCCESS)
            {
                LOGMSG_MSG_C("Send success! count: %d\n", count);
            }
            else
            {
                LOGMSG_ERR_C("Send fail!\n");
            }
            count++;

            int byteRecv = 0;
            retStatus = tcpServer.ServerRecv(clientHandle, recvData, byteRecv);
            if (retStatus == TCPCast::TCPStatus::SUCCESS && byteRecv > 0)
            {
                int countRecv = -1;
                memcpy(&countRecv, &recvData[0], sizeof(int));
                LOGMSG_MSG_C("Received count: %d byteRecv: %d\n", countRecv, byteRecv);
            }
        }
    }
    else
    {
        LOGMSG_ERR_C("Cannot InitComponent\n");
    }
}
void ClientWorker()
{
    std::vector<char> sendData;
    std::vector<char> recvData;
    TCPCast tcpClient;
    if (tcpClient.InitComponent(serverIP, 0, true) == TCPCast::TCPStatus::SUCCESS)
    {
        sendData.resize(4);
        recvData.resize(4);
        if (tcpClient.Connect(serverIP, serverPort) == TCPCast::TCPStatus::SUCCESS)
        {
            int count = 2000;
            while (true)
            {
                int byteRecv = 0;
                TCPCast::TCPStatus retStatus = tcpClient.ClientRecv(recvData, byteRecv);
                if (retStatus == TCPCast::TCPStatus::SUCCESS && byteRecv > 0)
                {
                    int countRecv;
                    memcpy(&countRecv, &recvData[0], sizeof(int));
                    LOGMSG_MSG_C("Received count: %d\n", countRecv);
                }

                memcpy(&sendData[0], &count, sizeof(int));
                retStatus = tcpClient.ClientSend(&sendData[0], sizeof(int));
                if (retStatus == TCPCast::TCPStatus::SUCCESS)
                {
                    LOGMSG_MSG_C("Send success! count: %d\n", count);
                }
                else
                {
                    LOGMSG_ERR_C("Send fail!\n");
                }
                count++;
                usleep(1000000); // 1 sec
            }
        }
    }
}
int main(int argc, char *argv[])
{
    std::thread serverTH(ServerWorker);
    serverTH.detach();
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::thread clientTH(ClientWorker);
    clientTH.detach();

    std::this_thread::sleep_for(std::chrono::seconds(10));
    return 0;
}

Output

$ ./src/TCPServerClient
20200502_104308_399 [MSG]                   TCPCast::                   Accept:   121, 20204,Received client 192.168.1.208:36946
20200502_104308_400 [MSG]              ServerWorker:    28, 20204,Send success! count: 0
20200502_104308_400 [MSG]              ClientWorker:    71, 20206,Received count: 0
20200502_104308_400 [MSG]              ClientWorker:    78, 20206,Send success! count: 2000
20200502_104308_400 [MSG]              ServerWorker:    42, 20204,Received count: 2000 byteRecv: 4
20200502_104308_400 [MSG]              ServerWorker:    28, 20204,Send success! count: 1
20200502_104309_400 [MSG]              ClientWorker:    71, 20206,Received count: 1
20200502_104309_400 [MSG]              ClientWorker:    78, 20206,Send success! count: 2001
20200502_104309_400 [MSG]              ServerWorker:    42, 20204,Received count: 2001 byteRecv: 4
20200502_104309_400 [MSG]              ServerWorker:    28, 20204,Send success! count: 2

Tools Example

Aim

This example is used to show tools example.

Source



#include <iostream>
#include <vector>

#include "Tools.h"

void IsNumberExample()
{
    std::cout << std::endl;
    std::cout << __FUNCTION__ << "-------------------" << std::endl;
    std::cout << Utility::IsNumber("9900") << std::endl;
    std::cout << Utility::IsNumber("99x00") << std::endl;
    std::cout << Utility::IsNumber("99.00") << std::endl;
    std::cout << Utility::IsNumber("99:00") << std::endl;
}
void SplitStringExample()
{
    std::cout << std::endl;
    std::cout << __FUNCTION__ << "-------------------" << std::endl;
    auto parts = Utility::SplitString("abd,cd,sfd,e", ',');
    for (const auto& part : parts)
    {
        std::cout << part << std::endl;
    }
}
void IsBigEndianExample()
{
    std::cout << std::endl;
    std::cout << __FUNCTION__ << "-------------------" << std::endl;
    std::cout << Utility::IsBigEndian() << std::endl;
}
void ReadFileToArrayExample()
{
    std::cout << std::endl;
    std::cout << __FUNCTION__ << "-------------------" << std::endl;
    std::vector<unsigned char> tempData;
    try
    {
        int readSize = Utility::ReadFileToArray("testing.txt", tempData);
        std::cout << "Read Size: " << readSize << std::endl;
    }
    catch (const std::string& err)
    {
        std::cout << err << std::endl;
    }
}
void ReplaceSubstringExample()
{
    std::cout << std::endl;
    std::cout << __FUNCTION__ << "-------------------" << std::endl;
    std::string strInput = "apple is orange and it is not an apple";
    Utility::ReplaceSubstring(strInput, "apple", "orange");
    std::cout << strInput << std::endl;
}
void ReplaceAllSubstringExample()
{
    std::cout << std::endl;
    std::cout << __FUNCTION__ << "-------------------" << std::endl;
    std::string strInput = "apple is orange and it is not an apple";
    Utility::ReplaceAllSubstring(strInput, "apple", "orange");
    std::cout << strInput << std::endl;
}
void GetFolderPathExample()
{
    std::cout << std::endl;
    std::cout << __FUNCTION__ << "-------------------" << std::endl;
    std::string strFolderPathLinux = "/Path/To/Your/File.txt";
    std::cout << "Linux example: " << Utility::GetFolderPath(strFolderPathLinux) << std::endl;
    std::string strFolderPathWindows = "C:\\Path\\To\\Your\\File.txt";
    std::cout << "Windows example: " << Utility::GetFolderPath(strFolderPathWindows) << std::endl;
}
void GetFileNameExample()
{
    std::cout << std::endl;
    std::cout << __FUNCTION__ << "-------------------" << std::endl;
    std::string strFolderPathLinux = "/Path/To/Your/File.txt";
    std::cout << "Linux example: " << Utility::GetFileName(strFolderPathLinux) << std::endl;
    std::string strFolderPathWindows = "C:\\Path\\To\\Your\\File.txt";
    std::cout << "Windows example: " << Utility::GetFileName(strFolderPathWindows) << std::endl;
}
void IsDirExistExample()
{
    std::cout << std::endl;
    std::cout << __FUNCTION__ << "-------------------" << std::endl;
    std::cout << "Linux example: " << Utility::IsDirExist("/Path/To/Your/Folder") << std::endl;
    std::cout << "Windows example: " << Utility::IsDirExist("C:\\Path\\To\\Your\\Folder") << std::endl;
}
void MakePathExample()
{
    std::cout << std::endl;
    std::cout << __FUNCTION__ << "-------------------" << std::endl;
    std::cout << "Create Path on linx: " << Utility::MakePath("./tempFolder") << std::endl;
}
int main(int argc, char *argv[])
{
    IsNumberExample();
    SplitStringExample();
    IsBigEndianExample();
    ReadFileToArrayExample();
    ReplaceSubstringExample();
    ReplaceAllSubstringExample();
    GetFolderPathExample();
    GetFileNameExample();
    IsDirExistExample();
    MakePathExample();
    return 0;
}

Output

$ ./src/Tools 

IsNumberExample-------------------
1
0
1
0

SplitStringExample-------------------
abd
cd
sfd
e

IsBigEndianExample-------------------
0

ReadFileToArrayExample-------------------
Read Size: 60

ReplaceSubstringExample-------------------
orange is orange and it is not an apple

ReplaceAllSubstringExample-------------------
orange is orange and it is not an orange

GetFolderPathExample-------------------
Linux example: /Path/To/Your
Windows example: C:\Path\To\Your

GetFileNameExample-------------------
Linux example: File.txt
Windows example: File.txt

IsDirExistExample-------------------
Linux example: 0
Windows example: 0

MakePathExample-------------------
Create Path on linx: 1

LinuxThread, Thread with Class, example for Linux

Aim

Sometime we want to attach a thread to a class. This example used Linux default thread. This example is Linux dependent. The basic idea is that once we create the class we let the thread loop in a member function.

Source



#include <iostream>
#include <thread>
#include <chrono>

#include "ClassWithThread.h"
#include "Logger.h"

int main(int argc, char *argv[])
{
    Logger::LoggerConfig config;
    config.logLevel = Logger::LogLevel::DEBUG;
    config.logPath = ".";
    config.fileSize = 0;
    config.fileSizeLimit = 4 * 1024 * 1024; // 4 MByte
    config.isToConsole = true;
    config.isToFile = false;
    LOGMSG_INIT(config);

    Trader cc;
    cc.InitComponent();
    std::this_thread::sleep_for(std::chrono::seconds(1));

    return 0;
}

Output

$ ./src/LinuxThread 
20200501_210847_578 [MSG]                    Trader::                     Main:    24, 18881,IN
20200501_210848_578 [MSG]                    Trader::                     Main:    31, 18881,OUT

Simple One mutex Message queue for Linux

Aim

This is an example to show 2 kind of message queue. The first one is using std library shared_ptr. The second one is using custom SmartPointer which is Linux dependence.

Source

github


#include <iostream>
#include <thread>
#include <chrono>

#include "MsgQ.h"
#include "DefaultMsgQ.h"

class BaseMsg
{
public:
    BaseMsg() {}
    virtual ~BaseMsg() {}

    void SetCount(int count) { m_count = count; }
    int GetCount() { return m_count; }
protected:
    int m_count;
};
class ChildMsg : public BaseMsg
{
public:
    ChildMsg() {}
    ~ChildMsg() {}
};

MsgQ<BaseMsg> m_msgQ;
void PushWorker()
{
    for (int i = 0; i < 3; i++)
    {
        std::shared_ptr<BaseMsg> msg = std::make_shared<ChildMsg>();
        msg->SetCount(i);
        m_msgQ.AddMsg(msg);
        std::cout << "Add Msg: " << i << std::endl;
    }
}
void PullWorker()
{
    int count = 0;
    while (count < 2)
    {
        std::shared_ptr<BaseMsg> msg;
        m_msgQ.GetMsg(msg);
        count = msg->GetCount();
        std::cout << "Get Msg: " << count << std::endl;
    }
}

DefaultMsgQ<BaseMsg> m_defaultMsgQ;
void PushWorker_Default()
{
    for (int i = 0; i < 3; i++)
    {
        SmartPointer<BaseMsg> msg = StaticCast<BaseMsg>(MakeSmartPointer<ChildMsg>());
        msg->SetCount(i);
        m_defaultMsgQ.AddMsg(msg);
        std::cout << "Add Msg: " << i << std::endl;
    }
}
void PullWorker_Default()
{
    int count = 0;
    while (count < 2)
    {
        SmartPointer<BaseMsg> msg;
        m_defaultMsgQ.GetMsg(msg);
        count = msg->GetCount();
        std::cout << "Get Msg: " << count << std::endl;
    }
}
int main(int argc, char *argv[])
{
    std::cout << "Msg Q example." << std::endl;
    std::thread pushTH(PushWorker);
    pushTH.detach();
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::thread pullTH(PullWorker);
    pullTH.detach();
    std::this_thread::sleep_for(std::chrono::seconds(1));

    std::cout << std::endl;
    std::cout << "Default Msg Q example." << std::endl;
    std::thread pushTH_Default(PushWorker_Default);
    pushTH_Default.detach();
    std::this_thread::sleep_for(std::chrono::seconds(1));
    std::thread pullTH_Default(PullWorker_Default);
    pullTH_Default.detach();
    std::this_thread::sleep_for(std::chrono::seconds(1));

    return 0;
}

Output

$ ./src/MsgQ 
Msg Q example.
Add Msg: 0
Add Msg: 1
Add Msg: 2
Get Msg: 0
Get Msg: 1
Get Msg: 2

Default Msg Q example.
Add Msg: 0
Add Msg: 1
Add Msg: 2
Get Msg: 0
Get Msg: 1
Get Msg: 2

Simple SmartPointer for Linux

Aim

This is a simple example of Smart Pointer in C++ for Linux. In case your project cannot support std library shared_ptr. You may try this one.

Source



#include <iostream>

#include "SmartPointer.h"

class Foo
{
public:
    Foo() { std::cout << "Hello from constructor" << std::endl; }
    ~Foo() { std::cout << "Hello from destructor" << std::endl; }

    void Print() { std::cout << "Hello from Foo" << std::endl; }
};
class BaseClass
{
public:
    BaseClass() { std::cout << "Hello from BaseClass constructor" << std::endl; }
    virtual ~BaseClass() { std::cout << "Hello from BaseClass destructor" << std::endl; }

    virtual void Print() {}
};
class ChildClass : public BaseClass
{
public:
    ChildClass() { std::cout << "Hello from ChildClass constructor" << std::endl; }
    ~ChildClass() { std::cout << "Hello from ChildClass destructor" << std::endl; }

    // override
    void Print() { std::cout << "Hello from ChildClass Print" << std::endl; }
};

void SimpleCase()
{
    {
        SmartPointer<Foo> foo = MakeSmartPointer<Foo>();
        foo->Print();
    }
    std::cout << "Hello from END" << std::endl;
}
void InheritCase_Print(SmartPointer<BaseClass> p)
{
    SmartPointer<BaseClass> pp = p;
    std::cout << "Print from Base ";
    pp->Print();
    std::cout << "Hello from END" << std::endl;
}
void InheritCase()
{
    std::cout << std::endl;
    SmartPointer<BaseClass> base = StaticCast<BaseClass>(MakeSmartPointer<ChildClass>());
    InheritCase_Print(base);
    SmartPointer<ChildClass> child = DynamicCast<ChildClass>(base);
    child->Print();
    std::cout << "Hello from END" << std::endl;
}
int main (int argc, char *argv[])
{
    SimpleCase();
    InheritCase();

    return 0;
}

Output

$ ./src/SmartPointer 
Hello from constructor
Hello from Foo
Hello from destructor
Hello from END

Hello from BaseClass constructor
Hello from ChildClass constructor
Print from Base Hello from ChildClass Print
Hello from END
Hello from ChildClass Print
Hello from END
Hello from ChildClass destructor
Hello from BaseClass destructor

Linux application installation example

Aim

This is an example to show how to use cmake to prepare a linux application and install it to a specific path with dynamic library.

Source



#include <iostream>

#include "Logger.h"

int main(int argc, char* argv[])
{
    LOGMSG_MSG_C("Hello\n");
    return 0;
}

Steps

$ cd InstallationExample
$ mkdir build install
$ cd build
$ cmake -G Ninja ../InstallationExample/ -DCMAKE_BUILD_TYPE=Debug -DCMAKE_INSTALL_PREFIX:PATH=../install
$ ninja
$ ninja install
$ cd ../install/bin
$ export LD_LIBRARY_PATH=Path to/install/lib
$ ./InstallationExample

Reference