分享 卡萨布兰卡,让您发霉的老代码重新发亮吧
前因
很多年前,我有个师兄,姓唐名朝,用 Delphi 开了一套单机软件,叫“智能中医诊断系统”,就是用户输入自己的症状,他那个软件就分析这些症状,有针对性的再问用户几个问题,最后给出一两个方子。当年他开发出来后,放到高交会上去展示,效果很好,他大喜,立马定价888元一套,结果买了大半年都只买了几套出去,房租又贵,只好关了公司重新打工去了。
前些天刚好本地有个单位叫我给他们的 DLL 算法程序弄一下压力测试,做的过程中突然想到了我那不太走运的师兄,如果他那套程序搬上网会怎么样呢?很有技术含量的啊,算法都用了一大堆,在网上一定会大发特发的吧?光是买春药广告都不得了。。。
卡萨布兰卡
去年,微软开源了代码为 Casablanca 的 C++ REST SDK,目的主要是为了让C++ 编程时更加方便的消费 RESTful 服务。但最近它新增了一项功能:New experimental features such as HTTP Listener library
,正是这项功能的出现,我认为它会成为一个比较具有潜力的项目,简单的说,利用 Casablanca,可以搭建起一个原生代码与云计算服务之间的双向桥梁,轻轻松松的把那些用C、C++、Delphi 甚至是 VB 写的单机程序转变成 Web 服务,让单机时代的优秀创意在云计算时代重新闪亮!
感受一下
准备DLL(假设说它就是您的过时代码)
作为示例,我们开发一个 DLL, 这个 DLL 调用 OpenCV 的图形处理功能将一张彩色图片转换为灰度图,代码如下,很简单:
#include "stdafx.h"
#include "TestFuncDLL.h"
#include <stdexcept>
#include <opencv\cv.h>
#include <opencv\highgui.h>
using namespace cv;
using namespace std;
namespace TestFuncs{
int MyTestFuncs::count = 0;
int MyTestFuncs::Gray(char* input, char* output){
Mat image;
image = imread(input, 1);
if (!image.data){
printf(" No image data \n ");
return -1;
}
Mat gray_image;
cvtColor(image, gray_image, CV_BGR2GRAY);
imwrite(output, gray_image);
return 0;
}
}
具体步骤为:
- 打开 VS 2013,新建一个 Win32 应用,在应用程序设置那一步选择“DLL”,建立一个 DLL 工程。
- 使用 NuGet 程序包管理器,安装 OpenCV 支持。
- 创建头文件和源文件,注意要加入
#define _CRT_SECURE_NO_DEPRECATE
,不然链接 OpenCV 时会报错。 - 编译,DLL 完工。
这里值得一提的是NuGet,这玩意儿用起来比 gem 还方便,搜索程序包,然后点安装,就完事了。如果不看看 Ruby 之外的东西,真不知道各家的技术都这么好用了。
C++ Web Service
不废话,直接上代码。不到100行就可以把一个原生代码函数开放成一个 json web service,您还等什么呢,压箱子底的老旧代码都拿出来吧!
这是侦听程序:
#include "stdafx.h"
#include "TestListener.h"
#include "TestFuncDLL.h"
#include <iostream>
#include <string>
using namespace std;
namespace TestService{
TestListener::TestListener(const http::uri& url) : m_litenser(http_listener(url))
{
m_litenser.support(methods::GET, tr1::bind(&TestListener::handle_get, this, tr1::placeholders::_1));
m_litenser.support(methods::POST, tr1::bind(&TestListener::handle_post, this, tr1::placeholders::_1));
try{
m_litenser.open().then([&](){ wcout << "Test listener started." << endl; }).wait();
while (true);
}
catch (exception const & e){
wcout << e.what() << endl;
}
}
void TestListener::handle_get(http_request request){
utility::string_t greeting = U("您好!您现在访问的是测试引擎...");
json::value::field_map answer;
answer.push_back(make_pair(json::value::string(U("greeting")), json::value::string(greeting)));
request.reply(status_codes::OK, json::value::object(answer));
}
int wCharToChar(const wchar_t *orig, char *nstring){
size_t origsize = wcslen(orig) + 1;
size_t convertedChars = 0;
wcstombs_s(&convertedChars, nstring, origsize, orig, _TRUNCATE);
return 0;
}
void handle_request(http_request request,
function<void(json::value &, json