一、c++
1. 安装cygwin (附带装上 boost ,bison, flex pkgconfig libtool, make)
2. 在cygwin中进入thrift根目录, ./configure ==> make ==> make install
3.编写thrift接口文件, 在cygwin中编写相应代码, 实现的地方用函数指针(接下来在vc中实现这些函数指针), 用gcc编译成dll.
代码如下:
接口文件Subsciber.thrift
service SubscriberServer {
void Test(1:string str),
}
Server.h
#ifndef _SERVERH_
#define _SERVERH_
#define EXPORT __declspec(dllexport)
typedef void (*TestFun)(unsigned char *, int);
extern "C"{
void EXPORT StartServer(TestFun testFun);
}
#endif
Server.cpp
// This autogenerated skeleton file illustrates how to build a server.
// You should copy it to another filename to avoid overwriting it.
#include <arpa/inet.h>
#include "SubscriberServer.h"
#include <thrift/protocol/TBinaryProtocol.h>
#include <thrift/server/TSimpleServer.h>
#include <thrift/transport/TServerSocket.h>
#include <thrift/transport/TBufferTransports.h>
#include "Server.h"
#include <stdio.h>
using namespace ::apache::thrift;
using namespace ::apache::thrift::protocol;
using namespace ::apache::thrift::transport;
using namespace ::apache::thrift::server;
using boost::shared_ptr;
//using namespace ;
TestFun _testFun = 0;
class SubscriberServerHandler : virtual public SubscriberServerIf {
public:
SubscriberServerHandler() {
// Your initialization goes here
}
void Test(const std::string& str) {
// Your implementation goes here
printf("Test\n");
std::string ss(str);
printf("%s\n", ss.c_str());
if(_testFun != NULL){
_testFun((unsigned char *)ss.c_str(), ss.length());// 由于这里传过去是utf8编码,故而传binary过去.在实现的地方转码.
}
}
};
void StartServer(TestFun testFun) {
printf("StartServer Begin\n");
_testFun = testFun;
int port = 9090;
shared_ptr<SubscriberServerHandler> handler(new SubscriberServerHandler());
shared_ptr<TProcessor> processor(new SubscriberServerProcessor(handler));
shared_ptr<TServerTransport> serverTransport(new TServerSocket(port));
shared_ptr<TTransportFactory> transportFactory(new TBufferedTransportFactory());
shared_ptr<TProtocolFactory> protocolFactory(new TBinaryProtocolFactory());
TSimpleServer server(processor, serverTransport, transportFactory, protocolFactory);
server.serve();
}
int main(){
StartServer(0);
}
Makefile:
all:
g++ -shared Server.cpp SubscriberServer.cpp SubscriberService_constants.cpp SubscriberService_types.cpp -L /usr/local/lib -l thrift -o SubscriberService.dll
4.在vc下新建win32工程.main函数所在文件内容为:
//extern "C"{
typedef void (* Test)(unsigned char *, int);
typedef void (* Do)();
typedef void (* StartServer)(Test);
//}
std::string UTF8ToS(const char* pu8, int utf8Len)
{
std::string str;
// convert an UTF8 string to widechar
int nLen = MultiByteToWideChar(CP_UTF8, 0, pu8, utf8Len, NULL, 0);
WCHAR* lpszW = NULL;
lpszW = new WCHAR[nLen];
int nRtn = MultiByteToWideChar(CP_UTF8, 0, pu8, utf8Len, lpszW, nLen);
if(nRtn != nLen)
{
delete[] lpszW;
return str;
}
// convert an widechar string to Multibyte
int MBLen = WideCharToMultiByte(CP_ACP, 0, lpszW, nLen, NULL, 0, NULL, NULL);
if (MBLen <=0)
{
return str;
}
char *pmb = new char[MBLen];
nRtn = WideCharToMultiByte(CP_ACP, 0, lpszW, nLen, pmb, MBLen, NULL, NULL);
delete[] lpszW;
if(nRtn != MBLen)
{
return str;
}
str = std::string(pmb);
delete []pmb;
return str;
}
void TestThis(unsigned char *buf, int len){
std::string ss = UTF8ToS((const char *)buf, len);
printf(ss.c_str());
printf("xyzoylz\r\n");
}
void DDD(){
//这个特别重要, 否则在dll内部调用IO相关的操作时会使用程序崩溃.
HMODULE h = LoadLibraryA("cygwin1.dll");
Do init = (Do)GetProcAddress(h, "cygwin_dll_init");
init();
HMODULE hDll;
StartServer startServerFun;
hDll = ::LoadLibraryExA("SubscriberService.dll",NULL,LOAD_WITH_ALTERED_SEARCH_PATH);
if (hDll != NULL)
{
startServerFun = (StartServer)GetProcAddress(hDll, "StartServer");
if (startServerFun != NULL)
{
startServerFun(TestThis);
}
}
FreeLibrary(hDll);
}
int _tmain(int argc, _TCHAR* argv[])
{
printf("_tmain() Begin\r\n");
DDD();
printf("_tmain() end\r\n");
return 0;
}
5. 拷贝c:/cygwin/bin/下的一些相关dll 及 刚才生成的SubscriberServer.dll到vc的Debug目录下.
6. 调试.
二、java
1. 重复一的(1)(2).
2. 安装jdk, ant.
3. 在windows下进入thrift根目录下的lib\java, 运行命令: ant
生成的文件却在lib\java\build下.
4. 编写接口文件, 实现接口.