CentOS 7 安装 MyCat 1.6

设置MyCat帐户:
vi conf/server.xml
<user name="mycatroot" defaultAccount="true">
    <property name="password">123456</property>
    <property name="schemas">MYCATDB</property>
    <property name="defaultSchema">MYCATDB</property>

MYCATDB为逻辑表名
设置读写分离:
vi conf/schema.xml
<schema name="MYCATDB" checkSQLschema="false" sqlMaxLimit="100" dataNode="dn1">
<dataNode name="dn1" dataHost="localhost1" database="数据库真实表名" />
<dataHost name="localhost1" maxCon="1000" minCon="10" balance="3"
    writeType="0" dbType="mysql" dbDriver="native" switchType="1"  slaveThreshold="100">
    <writeHost host="hostM1" url="192.168.146.133:3306" user="root" password="123456">
        <readHost host="hostS1" url="192.168.146.134:3306" user="dbread" password="123456"></readHost>
    </writeHost>

balance 属性
负载均衡类型,目前的取值有 3 种:
1. balance="0", 不开启读写分离机制,所有读操作都发送到当前可用的 writeHost 上。
2. balance="1",全部的 readHost 与 stand by writeHost 参与 select 语句的负载均衡,简单的说,当双主双从模式(M1->S1,M2->S2,并且 M1 与 M2 互为主备),正常情况下,M2,S1,S2 都参与 select 语句的负载均衡。
3. balance="2",所有读操作都随机的在 writeHost、readhost 上分发。
4. balance="3",所有读请求随机的分发到 wiriterHost 对应的 readhost 执行,writerHost 不负担读压力,
注意 balance=3 只在 1.4 及其以后版本有,1.3 没有。

writeType 属性:
1. writeType="0", 所有写操作发送到配置的第一个 writeHost,第一个挂了切到还生存的第二个 writeHost,重新启动后已切换后的为准,切换记录在配置文件中:dnindex.properties .
2. writeType="1",所有写操作都随机的发送到配置的 writeHost,1.5 以后废弃不推荐。

switchType 属性:
-1 表示不自动切换
1 默认值,自动切换
2 基于 MySQL 主从同步的状态决定是否切换
  心跳语句为 show slave status
3 基于 MySQL galary cluster 的切换机制(适合集群)(1.4.1)
  心跳语句为 show status like ‘wsrep%
做任何select语句均报错:
ERROR 1184 (HY000): Invalid DataSource:0
解决方法:
检查读写帐号密码是否可以正常连接读写库,如果出现:
ERROR 1129 (HY000): Host '192.168.146.133' is blocked because of many connection errors; unblock with 'mysqladmin flush-hosts'
则执行:
mysqladmin flush-hosts -uroot -p

CentOS 7 安装kafka

参考了 https://blog.csdn.net/q383965374/article/details/83348419

先安装Zookeeper
CentOS 7 安装 Zookeeper
http://kafka.apache.org/downloads tar xvzf kafka_2.13-2.6.0.tgz mv kafka_2.13-2.6.0 /usr/local/kafka_2.13-2.6.0 cd /usr/local/kafka_2.13-2.6.0 vi config/server.properties listeners=PLAINTEXT://192.168.146.128:9092 zookeeper.connect=192.168.146.128:2181,192.168.146.129:2181,192.168.146.130:2181 iptables -I INPUT -p tcp --dport 9092 -j ACCEPT service iptables save 启动服务器 bin/kafka-server-start.sh config/server.properties 输出 ... [2020-08-11 20:15:27,316] INFO [KafkaServer id=0] started (kafka.server.KafkaServer) 创建单分区单副本的topic test: bin/kafka-topics.sh --create --zookeeper 192.168.146.128:2181 --replication-factor 1 --partitions 1 --topic test 生产消息: bin/kafka-console-producer.sh --broker-list 192.168.146.128:9092 --topic test 然后输入想要发送的消息例如: Hello world! Hello Kafka! 消费消息: bin/kafka-console-consumer.sh --bootstrap-server 192.168.146.128:9092 --topic test --from-beginning 输出如下: Hello world! Hello Kafka! 停止服务器: bin/kafka-server-stop.sh config/server.properties Use Kafka GUI tools: https://kafkatool.com/download.html
添加自动启动
vi /lib/systemd/system/kafka.service
[Unit]
Description=Apache Kafka server (broker)
After=network.target zookeeper.service

[Service]
Type=idle
Environment=PATH=/usr/local/jdk1.8.0_261/bin:/usr/local/jdk1.8.0_261/jre/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/bin
User=root
Group=root
ExecStart=/usr/local/kafka_2.13-2.6.0/bin/kafka-server-start.sh /usr/local/kafka_2.13-2.6.0/config/server.properties
ExecStop=/usr/local/kafka_2.13-2.6.0/bin/kafka-server-stop.sh /usr/local/kafka_2.13-2.6.0/config/server.properties
Restart=on-failure

[Install]
WantedBy=multi-user.target


systemctl daemon-reload
systemctl start kafka
systemctl status kafka
systemctl enable kafka
安装php kafka扩展

git clone --depth 1 https://github.com/edenhill/librdkafka.git
cd librdkafka
./configure && make -j$(nproc) && make install
pecl install rdkafka

vi /etc/php.d/30-rdkafka.ini
extension=rdkafka.so
For php-fpm docker:
git clone --depth 1 https://github.com/edenhill/librdkafka.git
git clone https://github.com/arnaud-lb/php-rdkafka.git
docker cp librdkafka/ a8d307a3b81b:/root/
docker cp php-rdkafka/ a8d307a3b81b:/root/

docker exec -it a8d307a3b81b /bin/bash
cd /root/librdkafka
./configure
make clean && make && make install

cd /root/php-rdkafka
pecl install rdkafka
phpize
./configure --with-php-config=/usr/local/bin/php-config
make && make install
echo extension=rdkafka.so > /usr/local/etc/php/conf.d/docker-php-ext-rdkafka.ini
cat /usr/local/etc/php/conf.d/docker-php-ext-rdkafka.ini
php -m

CentOS 7 安装 Zookeeper

zookeeper安装先需要jdk环境

zk下载地址:http://mirror.bit.edu.cn/apache/zookeeper/

wget http://mirror.bit.edu.cn/apache/zookeeper/zookeeper-3.6.1/apache-zookeeper-3.6.1-bin.tar.gz
tar xvzf apache-zookeeper-3.6.1-bin.tar.gz
mv apache-zookeeper-3.6.1-bin /usr/local/zookeeper
cp /usr/local/zookeeper/conf/zoo_sample.cfg /usr/local/zookeeper/conf/zoo.cfg

mkdir /usr/local/zookeeper/data
mkdir /usr/local/zookeeper/logs
vi /usr/local/zookeeper/conf/zoo.cfg
dataDir=/usr/local/zookeeper/data
dataLogDir=/usr/local/zookeeper/logs

启动:
/usr/local/zookeeper/bin/zkServer.sh start

查看状态
/usr/local/zookeeper/bin/zkServer.sh status

查看已启动的zookeeper服务:
/usr/local/zookeeper/bin/zkCli.sh

iptables -I INPUT -p tcp --dport 2181 -j ACCEPT
service iptables save
添加自动启动
vi /lib/systemd/system/zookeeper.service
[Unit]
Description=ZooKeeper Service
After=network.target
After=syslog.target

[Service]
Type=forking
Environment=ZOO_LOG_DIR=/usr/local/zookeeper/logs
Environment=PATH=/usr/local/jdk1.8.0_261/bin:/usr/local/jdk1.8.0_261/jre/bin:/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/root/bin:/bin
User=root
Group=root
ExecStart=/usr/local/zookeeper/bin/zkServer.sh start /usr/local/zookeeper/conf/zoo.cfg
ExecStop=/usr/local/zookeeper/bin/zkServer.sh stop /usr/local/zookeeper/conf/zoo.cfg
ExecReload=/usr/local/zookeeper/bin/zkServer.sh restart /usr/local/zookeeper/conf/zoo.cfg
Restart=on-failure

[Install]
WantedBy=multi-user.target


systemctl daemon-reload
systemctl start zookeeper
systemctl status zookeeper
systemctl enable zookeeper
启动时失败,log:
java.io.IOException: Failed to bind to /0.0.0.0:8080
解决:
vi /usr/local/zookeeper/conf/zoo.cfg
admin.serverPort=8081

单线程、SSE、AVX运行效率对比

测试硬件:CPU-i5-4590
命令行:/arch:AVX
优化项:/O2

main.cpp

#include <iostream>
#include <vector>
#include "method.h"
#include <random>
#include <time.h>

using std::default_random_engine;
using std::uniform_real_distribution;

int main(int argc, char* argv[])
{
	//乘法累加运算
	{
		int size = 33;
		float *input1 = (float *)malloc(sizeof(float) * size);
		float *input2 = (float *)malloc(sizeof(float) * size);

		default_random_engine e;
		uniform_real_distribution<float> u(0, 1); //随机数分布对象 
		for (int i = 0; i < size; i++)
		{
			input1[i] = u(e);
			input2[i] = u(e);
		}

		int cntLoop = 10000000;

		clock_t start_t = clock();
		float org = 0.0;
		for (int i = 0; i < cntLoop; i++)
			org = MathMulAdd(input1, input2, size);
		printf("org = %f\t", org);
		printf("cost time: %d(ms)\n", clock() - start_t);

		start_t = clock();
		float sse = 0.0;
		for (int i = 0; i < cntLoop; i++)
			sse = SSEMulAdd(input1, input2, size);
		printf("sse = %f\t", sse);
		printf("cost time: %d(ms)\n", clock() - start_t);

		start_t = clock();
		float sse_ = 0.0;
		for (int i = 0; i < cntLoop; i++)
			sse_ = SSEFmAdd(input1, input2, size);
		printf("sse_= %f\t", sse_);
		printf("cost time: %d(ms)\n", clock() - start_t);

		start_t = clock();
		float avx = 0.0;
		for (int i = 0; i < cntLoop; i++)
			avx = AVXMulAdd(input1, input2, size);
		printf("avx = %f\t", avx);
		printf("cost time: %d(ms)\n", clock() - start_t);

		start_t = clock();
		float avx_ = 0.0;
		for (int i = 0; i < cntLoop; i++)
			avx_ = AVXFmAdd(input1, input2, size);
		printf("avx_= %f\t", avx_);
		printf("cost time: %d(ms)\n", clock() - start_t);

		free(input1);
		free(input2);
	}
	//结果:
	//org = 11.216135 cost time : 174(ms)
	//sse = 11.216136 cost time : 102(ms)
	//sse_ = 11.216136 cost time : 119(ms)
	//avx = 11.216136 cost time : 63(ms)
	//avx_ = 11.216136 cost time : 61(ms)


	//加法运算
	//{
	//	int size = 27;
	//	float *input = (float *)malloc(sizeof(float) * size);
	//	for (int i = 0; i < size; i++)
	//		input[i] = 0.0025;

	//	int cntLoop = 300000000;
	//	clock_t start_t = clock();
	//	float org = 0.0;
	//	for (int i = 0; i < cntLoop; i++)
	//		org = MathSum(input, size);
	//	printf("org = %f\t", org);
	//	printf("cost time: %d\n", clock() - start_t);

	//	start_t = clock();
	//	float sse = 0.0;
	//	for (int i = 0; i < cntLoop; i++)
	//		sse = SSESum(input, size);
	//	printf("sse = %f\t", sse);
	//	printf("cost time: %d\n", clock() - start_t);

	//	start_t = clock();
	//	float avx = 0.0;
	//	for (int i = 0; i < cntLoop; i++)
	//		avx = AVXSum(input, size);
	//	printf("avx = %f\t", avx);
	//	printf("cost time: %d\n", clock() - start_t);

	//	free(input);
	//}
	//结果:
	//org = 0.067500  cost time : 3062
	//sse = 0.067500  cost time : 2283
	//avx = 0.067500  cost time : 1829


	//最大值/最小值运算
	//{
	//	int size = 58;
	//	float *input = (float *)malloc(sizeof(float) * size);

	//	default_random_engine e;
	//	uniform_real_distribution<float> u(0, 3); //随机数分布对象 
	//	for (int i = 0; i < size; i++)
	//	{
	//		input[i] = u(e);
	//		printf("%f ", input[i]);
	//		if ((i + 1) % 8 == 0)
	//			printf("\n");
	//	}
	//	printf("\n");

	//	int cntLoop = 100000000;
	//	clock_t start_t = clock();
	//	float org;
	//	for (int i = 0; i < cntLoop; i++)
	//		org = MathMax(input, size);
	//	printf("org = %f\t", org);
	//	printf("cost time: %d(ms)\n", clock() - start_t);

	//	start_t = clock();
	//	float sse;
	//	for (int i = 0; i < cntLoop; i++)
	//		sse = SSEMax(input, size);
	//	printf("sse = %f\t", sse);
	//	printf("cost time: %d(ms)\n", clock() - start_t);

	//	start_t = clock();
	//	float avx;
	//	for (int i = 0; i < cntLoop; i++)
	//		avx = AVXMax(input, size);
	//	printf("avx = %f\t", avx);
	//	printf("cost time: %d(ms)\n", clock() - start_t);

	//	free(input);
	//}
	//结果:
	//org = 2.989384  cost time : 9491(ms)
	//sse = 2.989384  cost time : 1261(ms)
	//avx = 2.989384  cost time : 1413(ms)


	return 0;
}

method.h

#pragma once

#include <intrin.h>
#include <stdio.h>

float MathMulAdd(const float *input1, const float *input2, int size);
float SSEMulAdd(const float *input1, const float *input2, int size);
float SSEFmAdd(const float *input1, const float *input2, int size);
float AVXMulAdd(const float *input1, const float *input2, int size);
float AVXFmAdd(const float *input1, const float *input2, int size);


float MathSum(const float *input, int size);
float SSESum(const float *input, int size);
float AVXSum(const float *input, int size);


float MathMax(const float *input, int size);
float SSEMax(const float *input, int size);
float AVXMax(const float *input, int size);

method.cpp

#include "method.h"


float MathMulAdd(const float *input1, const float *input2, int size)
{
	float output = 0.0;
	for (int i = 0; i < size; i++)
	{
		output += input1[i] * input2[i];
	}
	return output;
}

float SSEMulAdd(const float *input1, const float *input2, int size)
{
	if (input1 == nullptr || input2 == nullptr)
	{
		printf("input data is null\n");
		return -1;
	}
	int nBlockWidth = 4;
	int cntBlock = size / nBlockWidth;
	int cntRem = size % nBlockWidth;

	float output = 0;
	__m128 loadData1, loadData2;
	__m128 mulData = _mm_setzero_ps();
	__m128 sumData = _mm_setzero_ps();
	const float *p1 = input1;
	const float *p2 = input2;
	for (int i = 0; i < cntBlock; i++)
	{
		loadData1 = _mm_load_ps(p1);
		loadData2 = _mm_load_ps(p2);
		mulData = _mm_mul_ps(loadData1, loadData2);
		sumData = _mm_add_ps(sumData, mulData);
		p1 += nBlockWidth;
		p2 += nBlockWidth;
	}
	sumData = _mm_hadd_ps(sumData, sumData); // p[0] + p[1] + p[4] + p[5] + ...
	sumData = _mm_hadd_ps(sumData, sumData); // p[2] + p[3] + p[6] + p[7] + ...
	output += sumData.m128_f32[(0)];         // 前4组

	for (int i = 0; i < cntRem; i++)
	{
		output += p1[i] * p2[i];
	}

	return output;
}

float SSEFmAdd(const float *input1, const float *input2, int size)
{
	if (input1 == nullptr || input2 == nullptr)
	{
		printf("input data is null\n");
		return -1;
	}
	int nBlockWidth = 4;
	int cntBlock = size / nBlockWidth;
	int cntRem = size % nBlockWidth;

	float output = 0;
	__m128 loadData1, loadData2;
	__m128 sumData = _mm_setzero_ps();
	const float *p1 = input1;
	const float *p2 = input2;
	for (int i = 0; i < cntBlock; i++)
	{
		loadData1 = _mm_load_ps(p1);
		loadData2 = _mm_load_ps(p2);
		sumData = _mm_fmadd_ps(loadData1, loadData2, sumData);
		p1 += nBlockWidth;
		p2 += nBlockWidth;
	}
	sumData = _mm_hadd_ps(sumData, sumData); // p[0] + p[1] + p[4] + p[5] + ...
	sumData = _mm_hadd_ps(sumData, sumData); // p[2] + p[3] + p[6] + p[7] + ...
	output += sumData.m128_f32[(0)];         // 前4组

	for (int i = 0; i < cntRem; i++)
	{
		output += p1[i] * p2[i];
	}

	return output;
}

float AVXMulAdd(const float *input1, const float *input2, int size)
{
	if (input1 == nullptr || input2 == nullptr)
	{
		printf("input data is null\n");
		return -1;
	}
	int nBlockWidth = 8;
	int cntBlock = size / nBlockWidth;
	int cntRem = size % nBlockWidth;

	float output = 0;
	__m256 loadData1, loadData2;
	__m256 mulData = _mm256_setzero_ps();
	__m256 sumData = _mm256_setzero_ps();
	const float *p1 = input1;
	const float *p2 = input2;
	for (int i = 0; i < cntBlock; i++)
	{
		loadData1 = _mm256_load_ps(p1);
		loadData2 = _mm256_load_ps(p2);
		mulData = _mm256_mul_ps(loadData1, loadData2);
		sumData = _mm256_add_ps(sumData, mulData);
		p1 += nBlockWidth;
		p2 += nBlockWidth;
	}
	sumData = _mm256_hadd_ps(sumData, sumData); // p[0] + p[1] + p[4] + p[5] + p[8] + p[9] + p[12] + p[13] + ... 
	sumData = _mm256_hadd_ps(sumData, sumData); // p[2] + p[3] + p[6] + p[7] + p[10] + p[11] + p[14] + p[15] + ... 
	output += sumData.m256_f32[(0)];            // 前4组
	output += sumData.m256_f32[(4)];            // 后4组

	for (int i = 0; i < cntRem; i++)
	{
		output += p1[i] * p2[i];
	}

	return output;
}

float AVXFmAdd(const float *input1, const float *input2, int size)
{
	if (input1 == nullptr || input2 == nullptr)
	{
		printf("input data is null\n");
		return -1;
	}
	int nBlockWidth = 8;
	int cntBlock = size / nBlockWidth;
	int cntRem = size % nBlockWidth;

	float output = 0;
	__m256 loadData1, loadData2;
	__m256 sumData = _mm256_setzero_ps();
	const float *p1 = input1;
	const float *p2 = input2;
	for (int i = 0; i < cntBlock; i++)
	{
		loadData1 = _mm256_load_ps(p1);
		loadData2 = _mm256_load_ps(p2);
		sumData = _mm256_fmadd_ps(loadData1, loadData2, sumData);
		p1 += nBlockWidth;
		p2 += nBlockWidth;
	}
	sumData = _mm256_hadd_ps(sumData, sumData); // p[0] + p[1] + p[4] + p[5] + p[8] + p[9] + p[12] + p[13] + ... 
	sumData = _mm256_hadd_ps(sumData, sumData); // p[2] + p[3] + p[6] + p[7] + p[10] + p[11] + p[14] + p[15] + ... 
	output += sumData.m256_f32[(0)];            // 前4组
	output += sumData.m256_f32[(4)];            // 后4组

	for (int i = 0; i < cntRem; i++)
	{
		output += p1[i] * p2[i];
	}

	return output;
}



float MathSum(const float *input, int size)
{
	float output = 0.0;
	for (int i = 0; i < size; i++)
	{
		output += input[i];
	}
	return output;
}

float SSESum(const float *input, int size)
{
	if (input == nullptr)
	{
		printf("input data is null\n");
		return -1;
	}
	int nBlockWidth = 4;
	int cntBlock = size / nBlockWidth;
	int cntRem = size % nBlockWidth;

	float output = 0;
	__m128 loadData;
	__m128 sumData = _mm_setzero_ps();
	const float *p = input;
	for (int i = 0; i < cntBlock; i++)
	{
		loadData = _mm_load_ps(p);
		sumData = _mm_add_ps(sumData, loadData);
		p += nBlockWidth;
	}
	sumData = _mm_hadd_ps(sumData, sumData); // p[0] + p[1] + p[4] + p[5] + ...
	sumData = _mm_hadd_ps(sumData, sumData); // p[2] + p[3] + p[6] + p[7] + ...
	output += sumData.m128_f32[(0)];         // 前4组

	for (int i = 0; i < cntRem; i++)
	{
		output += p[i];
	}

	return output;
}

float AVXSum(const float *input, int size)
{
	if (input == nullptr)
	{
		printf("input data is null\n");
		return -1;
	}
	int nBlockWidth = 8;
	int cntBlock = size / nBlockWidth;
	int cntRem = size % nBlockWidth;

	float output = 0;
	__m256 loadData;
	__m256 sumData = _mm256_setzero_ps();
	const float *p = input;
	for (int i = 0; i < cntBlock; i++)
	{
		loadData = _mm256_load_ps(p);
		sumData = _mm256_add_ps(sumData, loadData);
		p += nBlockWidth;
	}
	sumData = _mm256_hadd_ps(sumData, sumData); // p[0] + p[1] + p[4] + p[5] + p[8] + p[9] + p[12] + p[13] + ... 
	sumData = _mm256_hadd_ps(sumData, sumData); // p[2] + p[3] + p[6] + p[7] + p[10] + p[11] + p[14] + p[15] + ... 
	output += sumData.m256_f32[(0)];            // 前4组
	output += sumData.m256_f32[(4)];            // 后4组

	for (int i = 0; i < cntRem; i++)
	{
		output += p[i];
	}

	return output;
}


float MathMax(const float *input, int size)
{
	float maxVal = input[0];
	for (int i = 1; i < size; i++)
	{
		maxVal = maxVal > input[i] ? maxVal : input[i];
	}

	return maxVal;
}

float SSEMax(const float *input, int size)
{
	if (input == nullptr)
	{
		printf("input data is null\n");
		return -1;
	}
	int nBlockWidth = 4;
	int cntBlock = size / nBlockWidth;
	int cntRem = size % nBlockWidth;

	__declspec(align(16)) float output[4];
	__m128 loadData;
	const float *p = input;

	__m128 maxVal = _mm_load_ps(p);
	p += nBlockWidth;

	for (int i = 1; i < cntBlock; i++)
	{
		loadData = _mm_load_ps(p);
		maxVal = _mm_max_ps(maxVal, loadData);

		p += nBlockWidth;
	}
	_mm_store_ps(output, maxVal);

	float maxVal_ = output[0];
	for (int i = 1; i < 4; i++)
	{
		maxVal_ = maxVal_ > output[i] ? maxVal_ : output[i];
	}
	for (int i = 0; i < cntRem; i++)
	{
		maxVal_ = maxVal_ > p[i] ? maxVal_ : p[i];
	}

	return maxVal_;
}

float AVXMax(const float *input, int size)
{
	if (input == nullptr)
	{
		printf("input data is null\n");
		return -1;
	}
	int nBlockWidth = 8;
	int cntBlock = size / nBlockWidth;
	int cntRem = size % nBlockWidth;

	__declspec(align(32)) float output[8];
	__m256 loadData;
	const float *p = input;

	__m256 maxVal = _mm256_load_ps(p);
	p += nBlockWidth;

	for (int i = 1; i < cntBlock; i++)
	{
		loadData = _mm256_load_ps(p);
		maxVal = _mm256_max_ps(maxVal, loadData);

		p += nBlockWidth;
	}
	_mm256_store_ps(output, maxVal);

	float maxVal_ = output[0];
	for (int i = 1; i < 8; i++)
	{
		maxVal_ = maxVal_ > output[i] ? maxVal_ : output[i];
	}
	for (int i = 0; i < cntRem; i++)
	{
		maxVal_ = maxVal_ > p[i] ? maxVal_ : p[i];
	}

	return maxVal_;
}

gcc utf16 to utf32

int is_surrogate(char16_t uc) { return (uc - 0xd800u) < 2048u; }
int is_high_surrogate(char16_t uc) { return (uc & 0xfffffc00) == 0xd800; }
int is_low_surrogate(char16_t uc) { return (uc & 0xfffffc00) == 0xdc00; }
wchar_t surrogate_to_utf32(char16_t high, char16_t low) {
	return (high << 10) + low - 0x35fdc00;
}
void convert_utf16_to_utf32(const char16_t *input,
	size_t input_size,
	wchar_t *output)
{
	const char16_t * const end = input + input_size;
	while (input < end) {
		const char16_t uc = *input++;
		if (!is_surrogate(uc)) {
			*output++ = uc;
		}
		else {
			if (is_high_surrogate(uc) && input < end && is_low_surrogate(*input))
				*output++ = surrogate_to_utf32(uc, *input++);
			else {
				// ERROR
			}
		}
	}
}

//utf32 to utf16
size_t utf32_to_utf16(wchar_t src, char16_t* des)
{
	if (src == 0) return 0;

	if (src <= 0xFFFF)
	{
		if (des) (*des) = static_cast(src);
		return 1;
	}
	else
		if (src <= 0xEFFFF)
		{
			if (des)
			{
				des[0] = static_cast(0xD800 + (src >> 10) - 0x40);  // high
				des[1] = static_cast(0xDC00 + (src & 0x03FF));      // low
			}
			return 2;
		}
	return 0;
}
const String& BinaryReader::ReadUnicode()
{
	static String str;
	int count = ReadInt32();

	if (count > 0)
	{
		static char buffer[512];
		stream.read(buffer, count);
#ifndef __BUILD_IN_MSYS2
		str.assign(reinterpret_cast(buffer), count / sizeof(wchar_t));
#else
		int iDstLength = count / 2;
		wchar_t *wchDst = new wchar_t[iDstLength + 1];
		memset(wchDst, 0, sizeof(wchar_t) * (iDstLength + 1));
		convert_utf16_to_utf32((const char16_t *)buffer, iDstLength, wchDst);
		str = wchDst;
		delete[] wchDst;
		if (str.length() > iDstLength) {
			str = str.substr(0, iDstLength);
		}

		//to utf16
		char16_t *u16Str = new char16_t[iDstLength + 1];
		memset(u16Str, 0, sizeof(char16_t) * (iDstLength + 1));
		for (int i = 0; i < str.length(); i++) {
			utf32_to_utf16(str[i], u16Str + i);
		}

		//to utf32
		wchar_t *wchDst2 = new wchar_t[iDstLength + 1];
		memset(wchDst2, 0, sizeof(wchar_t) * (iDstLength + 1));
		convert_utf16_to_utf32((const char16_t *)u16Str, iDstLength, wchDst2);
		
		delete [] wchDst2;
		delete [] u16Str;
#endif

		return str;
	}

	str = L"";
	return str;
}

RobotFramework Ride安装

Install python-2.7.18.x86.msi
pip install robotframework
pip install robotframework-ride
#pip install -U D:\RIDE-1.7.4.2.zip
pip install robotframework-selenium2library

Start cmd with Admin:
pip install AutoItLibrary
pip install robotframework-autoitlibrary
pip list
cd C:\Python27\Lib\site-packages\AutoItLibrary\lib
regsvr32 /u AutoItX3.dll
regsvr32 /s AutoItX3.dll

Download PIL-1.1.7.win32-py2.7.exe:
http://pythonware.com/products/pil/

Run C:\Python27\Scripts\ride.py

Add testcase:
run  xxxx.exe
Get Screen Image  1.png

CMakeList.txt Demo

动态库:

PROJECT(ProjectName)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
#add_compile_definitions(BOOST_WINDOWS)
#add_compile_definitions(__BUILD_IN_MSYS2)
add_definitions(-D __BUILD_IN_MSYS2)
add_definitions(-D BOOST_LOG_DYN_LINK)
set(CMAKE_CXX_STANDARD 11) # C++11...
set(CMAKE_CXX_STANDARD_REQUIRED ON) #...is required...
SET(CMAKE_CXX_FLAGS "-std=c++11")
set(CMAKE_CXX_EXTENSIONS OFF) #...without compiler extensions like gnu++11
#set(HEADER_FILES /c/msys64/mingw64/x86_64-w64-mingw32/include/pthread.h)
#INCLUDE_DIRECTORIES("/c/msys64/mingw64/include")
#INCLUDE_DIRECTORIES("/d/code/ProjectName")
INCLUDE_DIRECTORIES("../Base")
INCLUDE_DIRECTORIES("/usr/include/mysql-cppconn/jdbc/")
#LINK_DIRECTORIES(/d/code/Base)
#LINK_DIRECTORIES(/c/msys64/mingw64/lib)
LINK_DIRECTORIES(../Image/Image)
LINK_DIRECTORIES(/usr/local/lib)
AUX_SOURCE_DIRECTORY(. DIR_SRCS)
AUX_SOURCE_DIRECTORY(../Base DIR_SRCS_BASE)
list(REMOVE_ITEM DIR_SRCS "Logger.h")
list(REMOVE_ITEM DIR_SRCS "Logger.cpp")
ADD_LIBRARY(ProjectName SHARED ${DIR_SRCS_BASE} ${DIR_SRCS_SCENE} ${DIR_SRCS_SCENE_DB} ${DIR_SRCS})
#TARGET_LINK_LIBRARIES(ProjectName Scene)
#TARGET_LINK_LIBRARIES(ProjectName Base)
TARGET_LINK_LIBRARIES(ProjectName Image)
TARGET_LINK_LIBRARIES(ProjectName boost_date_time)
TARGET_LINK_LIBRARIES(ProjectName boost_filesystem)
TARGET_LINK_LIBRARIES(ProjectName boost_iostreams)
TARGET_LINK_LIBRARIES(ProjectName boost_locale)
TARGET_LINK_LIBRARIES(ProjectName boost_log_setup)
TARGET_LINK_LIBRARIES(ProjectName boost_log)
TARGET_LINK_LIBRARIES(ProjectName boost_thread)
TARGET_LINK_LIBRARIES(ProjectName pthread)
TARGET_LINK_LIBRARIES(ProjectName z)
TARGET_LINK_LIBRARIES(ProjectName mysqlcppconn)
TARGET_LINK_LIBRARIES(ProjectName stdc++)

动态库:

PROJECT(Image)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
add_definitions(-D __BUILD_IN_MSYS2)
#add_compile_definitions(BOOST_WINDOWS)
add_definitions(-D IMAGE_EXPORTS)
set(CMAKE_CXX_STANDARD 11) # C++11...
set(CMAKE_CXX_STANDARD_REQUIRED ON) #...is required...
set(CMAKE_CXX_EXTENSIONS OFF) #...without compiler extensions like gnu++11
SET(CMAKE_CXX_FLAGS "-std=c++0x")
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC" )
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC" )
#set(HEADER_FILES /c/msys64/mingw64/x86_64-w64-mingw32/include/pthread.h)
#INCLUDE_DIRECTORIES("/c/msys64/mingw64/include")
INCLUDE_DIRECTORIES("/root/poco-poco-1.8.1-release/Foundation/include")
INCLUDE_DIRECTORIES("../jpeg")
INCLUDE_DIRECTORIES("../png")
INCLUDE_DIRECTORIES("../zlib")
INCLUDE_DIRECTORIES("../RectangleBinPack")
INCLUDE_DIRECTORIES("../CxImage")
LINK_DIRECTORIES(../CxImage)
LINK_DIRECTORIES(../jpeg)
LINK_DIRECTORIES(../png)
LINK_DIRECTORIES(../zlib)
LINK_DIRECTORIES(../RectangleBinPack)
#LINK_DIRECTORIES(/c/msys64/mingw64/lib)
AUX_SOURCE_DIRECTORY(. DIR_SRCS)
list(REMOVE_ITEM DIR_SRCS "Image.cpp")
ADD_LIBRARY(Image SHARED ${DIR_SRCS})
#set_property(TARGET Image PROPERTY POSITION_INDEPENDENT_CODE ON)
TARGET_LINK_LIBRARIES(Image CxImage)
TARGET_LINK_LIBRARIES(Image jpeg)
TARGET_LINK_LIBRARIES(Image png)
TARGET_LINK_LIBRARIES(Image zlib)
TARGET_LINK_LIBRARIES(Image RectangleBinPack)
TARGET_LINK_LIBRARIES(Image PocoFoundation)
TARGET_LINK_LIBRARIES(Image stdc++)

静态库:

PROJECT(CxImage)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
add_definitions(-D __BUILD_IN_MSYS2)
set(CMAKE_CXX_STANDARD 11) # C++11...
set(CMAKE_CXX_STANDARD_REQUIRED ON) #...is required...
set(CMAKE_CXX_EXTENSIONS OFF) #...without compiler extensions like gnu++11
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fPIC" )
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -fPIC" )
#set(HEADER_FILES /c/msys64/mingw64/x86_64-w64-mingw32/include/pthread.h)
#INCLUDE_DIRECTORIES("/c/msys64/mingw64/include")
AUX_SOURCE_DIRECTORY(. DIR_SRCS)
ADD_LIBRARY(CxImage STATIC ${DIR_SRCS})

可执行程序:

PROJECT(Test)
CMAKE_MINIMUM_REQUIRED(VERSION 2.8)
#add_compile_definitions(BOOST_WINDOWS)
#add_compile_definitions(__BUILD_IN_MSYS2)
add_definitions(-D __BUILD_IN_MSYS2)
add_definitions(-D BOOST_LOG_DYN_LINK)
set(CMAKE_CXX_STANDARD 11) # C++11...
set(CMAKE_CXX_STANDARD_REQUIRED ON) #...is required...
SET(CMAKE_CXX_FLAGS "-std=c++11")
set(CMAKE_CXX_EXTENSIONS OFF) #...without compiler extensions like gnu++11
#set(HEADER_FILES /c/msys64/mingw64/x86_64-w64-mingw32/include/pthread.h)
#INCLUDE_DIRECTORIES("/c/msys64/mingw64/include")
#INCLUDE_DIRECTORIES("../SceneBuilder")
#LINK_DIRECTORIES(/d/code/Base)
#LINK_DIRECTORIES(/d/code/Scene)
#LINK_DIRECTORIES(/c/msys64/mingw64/lib)
LINK_DIRECTORIES(../SceneBuilder)
LINK_DIRECTORIES(/usr/local/lib)
AUX_SOURCE_DIRECTORY(. DIR_SRCS)
add_executable(Test ${DIR_SRCS})
TARGET_LINK_LIBRARIES(Test SceneBuilder)
TARGET_LINK_LIBRARIES(Test boost_date_time)
TARGET_LINK_LIBRARIES(Test boost_filesystem)
TARGET_LINK_LIBRARIES(Test boost_iostreams)
TARGET_LINK_LIBRARIES(Test boost_locale)
TARGET_LINK_LIBRARIES(Test boost_log_setup)
TARGET_LINK_LIBRARIES(Test boost_log)
TARGET_LINK_LIBRARIES(Test boost_thread)
TARGET_LINK_LIBRARIES(Test pthread)
TARGET_LINK_LIBRARIES(Test stdc++)

编译:

cd /root/ProjectSrc
/usr/local/bin/cmake -DCMAKE_BUILD_TYPE=Release .
make