逝水流年

This is a blog to record my life, my work, my feeling …

Win 8 文件读写操作

啥也不说了,直接上代码。

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
#include <windows.h>;
#include <ppltasks.h>;
using namespace Platform;
using namespace Windows::Storage;
using namespace Windows::Storage::Streams;
using namespace Concurrency;
StorageFile^ openFile(String^ fileName)
{
    StorageFile^ file = nullptr;
    StorageFolder^ rootFolder = Windows::Storage::ApplicationData::Current->;LocalFolder;
    task<StorageFile^>;(rootFolder->;GetFileAsync(fileName)).then([&]\(task<StorageFile^>; getFileTask\)
    {
        try
        {
            file = getFileTask.get();
        }
        catch (Platform::Exception^ e)
        {
        }
    }).wait();
    return file;
}
Array<byte>;^ getFileContent(String^ fileName)
{
    Array<byte>;^ data = nullptr;
    StorageFile^ file = openFile(fileName);
    if (file)
    {
        task<IRandomAccessStream^>;(file->;OpenAsync(FileAccessMode::Read)).then([&]
(task<IRandomAccessStream^>; getStream)
        {
            auto readStream = getStream.get();
            DataReader^ dataReader=ref new DataReader(readStream);
            int length = readStream->;Size;
            if (length >; 0)
            {
                data = ref new Array<byte>;(length);
                task<unsigned int>;(dataReader->;LoadAsync(readStream->;Size)).then([&]\(task<unsigned
int>; loadTask\) {
                    loadTask.get();
                    dataReader->;ReadBytes(data);
                }).wait();
            }
        }).wait();
    }
    return data;
}
bool setFileContent(String^ fileName, unsigned char* data, int size)
{
    size_t totalWritten = 0;
    bool complete = false;
    StorageFile^ file = openFile(fileName);
    if (file)
    {
        IRandomAccessStream^ readStream = nullptr;
        task<IRandomAccessStream^>;(file->;OpenAsync(FileAccessMode::ReadWrite)).then([&]
(task<IRandomAccessStream^>; getStream)
        {
            readStream = getStream.get();
            DataWriter^ dataWriter = ref new DataWriter(readStream);
            Array<unsigned char>;^ arr = ref new Array<unsigned char>;(data, size);
            dataWriter->;WriteBytes(arr);
            task<unsigned int>;(dataWriter->;StoreAsync()).then([&]\(task<unsigned int>; writeTask)
            {
                try
                {
                    totalWritten = writeTask.get();
                } catch (Platform::Exception^ ex) {}
            }).wait();
            task<bool>;(dataWriter->;FlushAsync()).then([&]\(task<bool>; flushTask)
            {
                try
                {
                    complete = flushTask.get();
                } catch (Platform::Exception^ ex) {}
            }).wait();
            dataWriter->;DetachStream();
        }).wait();
    }
    return complete;
}

《重构》读书笔记一

一、重构之前一定要对原有代码有一套可靠的测试机制,并且测试要有自我检测能力。

第六章主要是讲的最简单的重构方法,就是对函数的重构。重构的目的就是要让函数更容易理解,思路更清晰。个人觉得重构的目的主要是针对开发者,能让维护者更容易理解而已。对函数的效率没有太多帮助,用作者的话来说就是应该放到优化中去做。有了易理解的函数,清晰的思路,优化起来那是事半功倍!

几个比较重要的重构的小方法:

1、Extract Methord:提取函数。将大函数分解为多个独立功能的小函数。小函数更容易阅读和理解。

2、Replace Temp with Quary:用查询函数替换局部变量。过多的局部变量会影响阅读。

3、Replace Methord with Methord Object:用函数对象替换函数。

将win32的lib库直接转为winRT静态库

将win32的lib库直接转为winRT静态库需要注意三点

1、打开/ZW开关,关闭/GM开关

2、忽略OLE32.LIB

3、手动使用命令/AI包含Windows.winmd(从工程中add new references无效) /FU Platform.winmd /FU Windows.winmd /AI “$(VCInstallDir)vcpackages” /AI “$(WindowsSDK_MetadataPath)”

剩余的工作就是修改编译错误了

Windows Runtime Component理解

WinRT类型的动态库,可以认为导出的是类,应用通过创建类的实例来引用该导出类的功能即接口。

这里需要注意的是导出类的public成员只能是接口(成员变量是不可以为public),这样就避免了暴露类结构,并且接口中的参数不能为native type(例如:void* dd就不可以作为参数)。

谈Lambda表达式

最近由于再开发Win 8 metro程序和准备开发Win Phone 8 App,学习了下WinRT开发,包括一些C++ 11新标准内容,最初对Lamdba表达式的表达很是头疼,对以往的编程认识非常不同,这也就让我对它产生了浓厚的兴趣,找了很多资料来学习它,并且写了好多程序去测试它,慢慢发现其实Lamdba表达式真的很有趣!

其实对Lambda表达式不必有任何的畏惧心里,通过仔细的分析它,我发现其实Lambda表达式就是一个函数,是一个匿名的函数,是一个可以自己执行的自己的函数。就这么简单!下面我们来看一个例子:

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
#include <functional>;
#include <iostream>;
using namespace std;
int main(int argc, char argv[])
{
    int number = 2;
    int menber = 2;
    // []表示要使用到的作用域外的变量
    // ()传入的参数
    // mutable: 对number 来说,number是值传递,如果要修改的话,需要mutable标记,否则可以使用引用传递.
    // throw:抛出异常
    // -> 后跟返回值
    // {} 函数题
    auto f1 = [number, &menber]\(int x, int y\) mutable throw() -> int {
        ++number;
        ++menber;
        return x + y;
    };
    //Lambda表达式执行之前
    cout << "number:" << number << " menber:" << menber << endl;
    //执行Lambda表达式
    f1(3, 4);
    //Lambda表达式执行之后
    cout << "number:" << number << " menber:" << menber << endl;
    //自我执行
    cout << []\(int x, int y\) { return x + y; }(2, 3) << endl;
    // auto类型其实就是 function<int (int, int)>;.
    function<int (int, int)>; f2 = []\(int x, int y\) { return x + y; };
    cout << f2(3,4) << f1(3, 4) << endl;
    system("pause");
    return 0;
}

Std::string 与 Std::wstring 转换方法的效率比较

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
// Calls the provided work function and returns the number of milliseconds
// that it takes to call that function.
template <class Function>;
__int64 time_call(Function&& f)
{
    __int64 begin = GetTickCount64();
    f();
    return GetTickCount64() - begin;
}
// Use WideCharToMultiByte and MultiByteToWideChar
string WChar2Ansi(const wchar_t* pwszSrc)
{
    int nLen = WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, NULL, 0, NULL, NULL);
    if (nLen<= 0) return string("");
    char* pszDst = new char[nLen];
    if (NULL == pszDst) return string("");
    WideCharToMultiByte(CP_ACP, 0, pwszSrc, -1, pszDst, nLen, NULL, NULL);
    pszDst[nLen -1] = 0;
    string strTemp(pszDst);
    delete [] pszDst;
    return strTemp;
}
wstring Ansi2WChar(const char* pszSrc, int nLen)
{
    int nSize = MultiByteToWideChar(CP_ACP, 0, pszSrc, nLen, 0, 0);
    if(nSize <= 0) return NULL;
    wchar_t *pwszDst = new wchar_t[nSize+1];
    if( NULL == pwszDst) return NULL;
    MultiByteToWideChar(CP_ACP, 0, pszSrc, nLen, pwszDst, nSize);
    pwszDst[nSize] = 0;
    if( pwszDst[0] == 0xFEFF)                    // skip Oxfeff
        for(int i = 0; i < nSize; i ++)
            pwszDst[i] = pwszDst[i+1];
    wstring wcharString(pwszDst);
    delete pwszDst;
    return wcharString;
}
// Use wcstombs_s and mbstowcs_s
string ws2s(wstring ws)
{
    const wchar_t* Source = ws.c_str();
    size_t size = 2 * ws.size() + 1;
    char* Dest = new char[size];
    memset(Dest,0, size);
    size_t len = 0;
    wcstombs(Dest, Source, size);
    //wcstombs_s(&len, Dest, size, Source, size);
    string result = Dest;
    delete [] Dest;
    return result;
}
wstring s2ws(string s)
{
    const char* Source = s.c_str();
    size_t size = s.size() + 1;
    wchar_t* Dest = new wchar_t[size];
    wmemset(Dest, 0, size);
    size_t len = 0;
    mbstowcs(Dest, Source, size);
    //mbstowcs_s(&len, Dest, size, Source, size);
    wstring result = Dest;
    delete [] Dest;
    return result;
}
// Testing
    __int64 elapsed;
    string input = "Hello, World.\\XXX\\XXX";
    wstring winput = L"Hello, World.\\XXX\\XXX";
    wchar_t dest[1000];
    int count = 10000;
    elapsed = time_call([input, &count]
    {
        while (count)
        {
            Ansi2WChar(input.c_str(), input.length());
            count--;
        }
    });
    memset(dest, 0, 1000);
    _itow_s(elapsed, dest, 10);
    OutputDebugStringW(L"Time:");
    OutputDebugStringW(dest);
    OutputDebugStringW(L"ms\n");
    count = 10000;
    elapsed = 0;
    elapsed = time_call([input, &count]
    {
        while (count)
        {
            s2ws(input);
            count--;
        }
    });
    memset(dest, 0, 1000);
    _itow_s(elapsed, dest, 10);
    OutputDebugStringW(L"Time:");
    OutputDebugStringW(dest);
    OutputDebugStringW(L"ms\n");
    count = 10000;
    elapsed = 0;
    elapsed = time_call([winput, &count]
    {
        while (count)
        {
            WChar2Ansi(winput.c_str());
            count--;
        }
    });
    memset(dest, 0, 1000);
    _itow_s(elapsed, dest, 10);
    OutputDebugStringW(L"Time:");
    OutputDebugStringW(dest);
    OutputDebugStringW(L"ms\n");
    count = 10000;
    elapsed = 0;
    elapsed = time_call([winput, &count]
    {
        while (count)
        {
            ws2s(winput);
            count--;
        }
    });
    memset(dest, 0, 1000);
    _itow_s(elapsed, dest, 10);
    OutputDebugStringW(L"Time:");
    OutputDebugStringW(dest);
    OutputDebugStringW(L"ms\n");

输出:

Time:78ms

Time:94ms

Time:62ms

Time:109ms

从输出结果可以看出

WideCharToMultiByte和MultiByteToWideChar转换效率要比mbstowcs和wcstombs高。

注意:如果使用mbstowcs则需要Disable Specific Warnings:4996

如何将Metro 程序需要的文件加入到app运行目录(AppX文件夹中)

1、将文件加到工程中

2、选中文件,右键属性->Content->True

C++ Metro App 同C# Metro App 引用winmd库方法

1、 C++ Metro App :AddReference

Project->Properties->Common Properties->Framework and References->Add new Reference…

2、 C# Metro App :AddReference

Right click References folder orRight click Project->Add Reference

在类中定义引用类型成员变量

在类中可以定义引用类型的成员变量,但是必须在构造函数之前完成初始化,也就是必须在构造函数的初始化列表中完成初始化。

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
class Functor
{
public:
    // The constructor.
    explicit Functor(int& evenCount)
        : _evenCount(evenCount)
    {
        //_evenCount = evenCount;
    }
    // The function-call operator prints whether the number is
    // even or odd. If the number is even, this method updates
    // the counter.
    void operator()(int n)
    {
        cout << n;
        if (n % 2 == 0)
        {
            cout << " is even " << endl;
            // Increment the counter.
            _evenCount++;
        }
        else
        {
            cout << " is odd " << endl;
        }
    }
private:
    int& _evenCount; // the number of even variables in the vector
};

注意如果将初始化列表去掉,改为在构造函数中初始化,则编译器会提示: error C2758: ‘Functor::_evenCount’ : must be initialized in constructor base/member initializer list

动态库和静态库都是库

最近一直在折腾动态库,静态库,N多个库,编译,连接,排查link error,搞的头都大了!真奇怪为什么要搞那么多库!功能是分的很清楚了,但是没人了解全部了,三个国家的人再搞,没有一个整体负责的人,没有说明,只能看代码,摸索!终于搞定了吧,又得merge到其他breach上,又是新的一轮编译,连接,排查!

终于在下班前搞定了,虽然还有点小问题,但是已经基本正常了,谢天谢地~,给其他同事讲解的时候,还是比较自豪的,哈哈,这么多的东西,要搞懂还真不容易那