改用C++生成自动化数据表
前面的文章中,我们讨论了使用一个基于.NET的第三方程序库来从程序中来生成数据表。在我看来,这整个思路是非常有用的,例如为显示测试结果。我经常会自己在博客中尝试各种像这样的方法。大体上就像你做各种测试然后把结果输出到控制台或者文本文档中……
但是,要是把结果直接写入电子表格然后自动化地生成可视化图表不就更好了吗?这种方法也可以用C++实现吗?
简介
在上面提过的文章中,我给大家演示了如何将测试结果直接输出到Excel文件中。我用了一个很棒的的程序库它叫做 Spire.XLS。不仅是表格,图表也能很轻松地绘制出来!不仅如此,如果你细心发现,它还可以实现数据的计算,预测,运算等。
这些在.NET环境下都可以实现,在这呢我尝试了下用C++ 也就是原代码的主意 – 原语言。
简而言之,我们用C++/CLI作为源代码和托管代码之间的桥梁。
以这种方法,我们可以用疯狂的最优源代码高速运行我们的算法和标准检查程序。结束的时候的,我们仅仅把结果传输到报表产生器模块。然后我们就有了可以进行分析的数据表。
当然另一种方法就是把结果从文本文档(或者控制台)复制到电子数据表中。我以前经常这么干,但不得不说这经常耗费很多时间。
处理来自源代码的调用
从C#调用C++十分简便。你要做的就是用些PInvoke方法以及互操作机制(Interoperability mechanisms)然后从托管代码中调用原函数。
但是呢,我们怎样从C++中调用C#?换句话说:怎样逆用PInvoke
?
幸运的是,这应该也不是难事:
1 我们要在C++的公共语言运行时中创建一个数据表模块的动态链接街库(也就是DLL)文件。
2 C++的公共语言运行库允许我们在C#(.NET)中使用第三方程序库
3 在原代码中我们可以使用上面的DLL作为`normal Dll`.
4 我是根据这篇教程实现的:tigerang/reverse-pinvoke
通常像这种交互操作中,当你想从一端传送复杂数据到另一端(托管/原)时,事情就会变的很复杂。在我的示例中,我会只用 framework可以自动处理的简单的,基本的类型。
实现
源代码下载: github.com/fenbf/AutoPerfReport
数据表生成器接口:C++/CLI
#ifdef REPORTER_EXPORTS
#define REPORTER_API __declspec(dllexport)
#else
#define REPORTER_API __declspec(dllimport)
#endif
namespace reporter
{
class REPORTER_API Reporter
{
private:
class *Result _results;
public:
Reporter();
~Reporter();
void AddResult( const char *colName, int n, double elapsedTime);
void SaveToFile( const char *fname);
};
}
这个接口不是通用的。但是用于简单的测试还是可以的。每次测试运行你要用测试名调用AddResult方法,n 是测试程序的大小和elapsedTime。
原代码:
{
for(auto &test : perfTests)
{
test->run(n);
report.AddResult(test->name(), n, pt->elapsedTimeSec());
}
}
为了保存结果,我用了名为 map的示意图:
{
public:
std::map<std:: string, std::map< int, double>> _res;
};
这张示意图是用来存储测试实例的(它的名字),示意图上的数字‘N’和所用时间来存储这种测试运行。
所以 _res["hello"][100] –
意味着测试运行100个元素的’hello’所用的时间。
下面是主方法:
{
Workbook ^workbook = gcnew Workbook();
workbook->CreateEmptySheets( 2);
String ^range = "";
String ^labelRange = "";
writeData(_results, workbook, range, labelRange);
createChart(workbook, range, labelRange);
std::cout << " Workbook with data created! " << std::endl;
String ^filename = gcnew String(fname);
workbook->SaveToFile(filename, ExcelVersion::Version2007);
std::cout << " Workbook written to " << fname << std::endl;
}
C++ CLI代码看上去很像C#,但是他有一些有趣的元素:-)
从命名上就可以猜出writeData
和createChart
方法是将数据写入电子表格(填入列)并且基于这些数据制作相应的图表。
在以上的示例中我用Spire.XLS库受益良多。这是非常容易上手并且容易使用的模块。我用过的是免费版(每个文件最多150行) - 但这对于我大多的实例来说足够用了。
这个程序库数要是让我们在系统中没安装Office的情况下对XLS文件进行操作。另外我在添加相关引用在 Visual Studio 2013 Express甚至在C++ CLI时都没有任何问题。当然他在任何2.0以上版本的.NET Framework上都完美运行。
输出结果
事实上我的原/托管 示例的运行结果和我上篇文章一模一样。和我预想的一样:)
Spire.XLS 库可以创建文档,添加行,生成图表并且可以成功保存到硬盘。当然,这里测试结果好似来自原代码而不是托管代码。
总结
在以上示例中我向大家展示了如何简单地把测试结果从原代码中输出到电子表格文件中。Spire.XLS 库让我们仅仅用几行代码就可以创建文件,并用图表展示运算结果。
在简单的测试示例我们可以随意,但是当你开发一些大的工程的话这种自动化操作会节省很多时间。