This commit is contained in:
Saturneic 2019-01-14 18:35:09 +08:00
parent 42cae7ac2e
commit b9f8ddaaf7
6 changed files with 345 additions and 147 deletions

View File

@ -9,6 +9,7 @@
/* Begin PBXBuildFile section */
9221DA1121EB5FB8007310A7 /* net.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 9221DA1021EB5FB8007310A7 /* net.cpp */; };
925A13A621EC68D500CBD427 /* cpart.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 925A13A421EC67C900CBD427 /* cpart.cpp */; };
925A13A921EC973000CBD427 /* cmap.cpp in Sources */ = {isa = PBXBuildFile; fileRef = 925A13A721EC973000CBD427 /* cmap.cpp */; };
/* End PBXBuildFile section */
/* Begin PBXCopyFilesBuildPhase section */
@ -30,6 +31,8 @@
9221DA1421EB62F6007310A7 /* cpart.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cpart.h; sourceTree = "<group>"; };
9221DA1621EB8C02007310A7 /* pcs.map */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.module-map"; name = pcs.map; path = build/Debug/PCS/pcs.map; sourceTree = "<group>"; };
925A13A421EC67C900CBD427 /* cpart.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = cpart.cpp; sourceTree = "<group>"; };
925A13A721EC973000CBD427 /* cmap.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = cmap.cpp; sourceTree = "<group>"; };
925A13A821EC973000CBD427 /* cmap.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = cmap.h; sourceTree = "<group>"; };
/* End PBXFileReference section */
/* Begin PBXFrameworksBuildPhase section */
@ -62,15 +65,25 @@
9221DA0E21EB5FAD007310A7 /* Net */ = {
isa = PBXGroup;
children = (
925A13AA21EC989500CBD427 /* include */,
9221DA1021EB5FB8007310A7 /* net.cpp */,
9221DA0F21EB5FB8007310A7 /* net.h */,
9221DA1421EB62F6007310A7 /* cpart.h */,
9221DA1621EB8C02007310A7 /* pcs.map */,
925A13A421EC67C900CBD427 /* cpart.cpp */,
925A13A721EC973000CBD427 /* cmap.cpp */,
);
name = Net;
sourceTree = "<group>";
};
925A13AA21EC989500CBD427 /* include */ = {
isa = PBXGroup;
children = (
9221DA0F21EB5FB8007310A7 /* net.h */,
9221DA1421EB62F6007310A7 /* cpart.h */,
925A13A821EC973000CBD427 /* cmap.h */,
);
name = include;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXNativeTarget section */
@ -129,6 +142,7 @@
files = (
9221DA1121EB5FB8007310A7 /* net.cpp in Sources */,
925A13A621EC68D500CBD427 /* cpart.cpp in Sources */,
925A13A921EC973000CBD427 /* cmap.cpp in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

160
cmap.cpp Normal file
View File

@ -0,0 +1,160 @@
//
// cmap.cpp
// Net
//
// Created by 胡一兵 on 2019/1/14.
// Copyright © 2019年 Bakantu. All rights reserved.
//
#include "cmap.h"
CMap::CMap(string path){
ifstream map;
map.open(path+"/pcs.map");
this->path = path;
// 如果文件存在且打开成功
if(map.good()){
string line;
map>>line;
// 读取计算模块信息
if(line == "#PCS"){
BuildCPart(map);
}
map>>line;
// 读取计算模块之间的依赖关系信息
if(line == "#DEPEND"){
BuildConnection(map);
}
}
else throw "fail to open pcs.map";
}
void CMap::BuildCPart(ifstream &map){
string line;
map>>line;
// 从初始行开始读取在描述结束符之前的所有行
while(line!="END"){
// 定位括号,来截取计算模块的名字
unsigned long qs = line.find('(',0), qe = line.find(')',0);
string name = line.substr(qs+1,qe-qs-1);
// 定位尖括号来截取计算模块所在源文件的名字
qs = line.find('<',0);
qe = line.find('>',0);
string src_name = line.substr(qs+1,qe-qs-1);
// 根据以上信息构造计算管理结构对象
CPart *ncp = new CPart(path,src_name,name);
// 在列表中加入该对象
this->cparts.insert(pair<string,CPart *>(name,ncp));
// 构造该计算模块的输入与输出形式参数列表
vector<int>fargs_in,fargs_out;
map>>line;
if(line[0] == '>'){
fargs_in = BuidArgs(line);
}
map>>line;
if(line[0] == '<'){
fargs_out = BuidArgs(line);
}
// 设置输入与输出形式参数列表
ncp->setArgsType(fargs_in, fargs_out);
// 读入下一行
map>>line;
}
}
vector<int> CMap::BuidArgs(string &line){
vector<int> fargs;
unsigned long qs,qe;
// 定位方括号来获得函数的作用域
qs = line.find('[',0);
qe = line.find(']',0);
unsigned long idx = qs;
while(idx < qe){
unsigned long ts,te;
// 截取冒号与逗号之间的类型信息
ts = line.find(':',idx);
te = line.find(',',ts);
if(te == string::npos){
te = qe;
}
string type = line.substr(ts+1,te-ts-1);
// 在形式参数列表中加入类型信息
if(type == "int")
fargs.push_back(INT);
else if(type == "double")
fargs.push_back(DOUBLE);
// 向下移动
idx = te;
}
return fargs;
}
void CMap::BuildConnection(ifstream &map){
string line;
map>>line;
// 从初始行开始读取在描述结束符之前的所有行
while(line != "END"){
// 定位圆括号来截取计算模块的名字
unsigned long qs = line.find('(',0), qe = line.find(')',0);
string name = line.substr(qs+1,qe-qs-1);
// 通过计算模块的名字在参数列表中找到对应的计算模块
CPart *p_ncp = cparts.find(name)->second;
// 定位大括号来截取依赖模块的列表
unsigned long idx = line.find('{',qe);
unsigned long ss = line.find('}',idx);
unsigned long ts, te;
while(idx+1 < ss){
// 定位圆括号与方括号来截取依赖的计算模块的名字及依赖的相关参数信息
ts = line.find('(',idx);
te = line.find(']',ts);
if(te == string::npos){
te = ss;
}
// 在计算模块管理结构中添加构造的依赖信息管理结构
string item = line.substr(ts,te-ts+1);
p_ncp->depends.push_back(ReadItem(item));
//cout<<item<<endl;
// 向下移动
idx = te+1;
}
map>>line;
}
}
Depends CMap::ReadItem(string item){
// 构造依赖关系信息结构
Depends dep;
// 定位圆括号来截取计算模块的名字
unsigned long qs = item.find('(',0), qe = item.find(')',qs);
string name = item.substr(qs+1,qe-qs-1);
// 通过模块名字在模块列表中找到相应模块
dep.t_cpart = cparts.find(name)->second;
// 定位方括号来截取依赖参数信息
unsigned long idx = item.find('[',0),ss = item.find(']',idx);
unsigned long ts, te;
while(idx < ss){
ts = idx;
te = item.find(',',ts+1);
if(te == string::npos){
te = ss;
}
// 将字符串转换为整数
string arg = item.substr(ts+1,te-ts-1);
std::stringstream sstr;
int darg;
sstr<<arg;
sstr>>darg;
// 加入依赖参数序号信息
dep.args.push_back(darg);
// 向下移动
idx = te;
}
return dep;
}

41
cmap.h Normal file
View File

@ -0,0 +1,41 @@
//
// cmap.hpp
// Net
//
// Created by 胡一兵 on 2019/1/14.
// Copyright © 2019年 Bakantu. All rights reserved.
//
#ifndef cmap_h
#define cmap_h
#include "cpart.h"
#include <map>
#include <fstream>
#include <sstream>
using std::map;
using std::ifstream;
using std::pair;
//计算任务无环有向图管理
class CMap{
public:
// 图中包含的的计算模块列表
map<string,CPart *> cparts;
// 图目录所在的目录
string path;
// 构造函数传入图包所在的目录
CMap(string path);
// 根据图的表述文件构造计算模块列表
void BuildCPart(ifstream &map);
// 根据图表述文件中的描述信息,处理并转化为形式输入或输出参数列表
vector<int> BuidArgs(string &line);
// 根据图的表述文件构造计算模块之间的依赖关系
void BuildConnection(ifstream &map);
// 根据图描述文件依赖关系描述语句所提供的信息转化为依赖关系结构
Depends ReadItem(string item);
};
#endif /* cmap_h */

View File

@ -8,47 +8,103 @@
#include "cpart.h"
CPart::CPart(string src_path,string src_name,string name){
/**
@param src_path
@param src_name
@param name
@param ffresh
*/
CPart::CPart(string src_path,string src_name,string name,bool ffresh = true){
this->src_path = src_path;
this->name = name;
// 去掉源文件的后缀
unsigned long qp = src_name.find(".",0);
string t_libname = "lib"+src_name.substr(0,qp)+".so";
if(!~access(("Libs/"+t_libname).data(), F_OK)){
system(("g++ -fPIC -shared -std=c++11 -o ./Libs/"+t_libname+" "+src_path+"/"+src_name).data());
if(qp == string::npos){
qp = src_name.size()-1;
}
// 生成lib文件的文件名
string t_libname = "lib"+src_name.substr(0,qp)+".so";
// 如果lib文件存在且不要求每次建立该结构都重新编译一次源文件的话就不执行编译
if(!~access(("Libs/"+t_libname).data(), F_OK) || ffresh)
BuildSo();
// 记录必要信息
this->libname = t_libname;
this->handle = dlopen(("Libs/"+t_libname).data(), RTLD_NOW | RTLD_GLOBAL);
this->func = (PCSFUNC) dlsym(this->handle, this->name.data());
this->libargs_in = (vector<void *> *) dlsym(this->handle, ("__"+name+"_args_in").data());
this->libargs_out = (vector<void *> *) dlsym(this->handle, ("__"+name+"_args_out").data());
this->src_name = src_name;
}
CPart::CPart(string name){
this->name = name;
this->libname = "lib"+name+".so";
this->handle = dlopen(this->libname.data(), RTLD_LAZY | RTLD_GLOBAL);
/**
@return 0
*/
int CPart::BuildSo(void){
int rtn = system(("g++ -fPIC -shared -std=c++11 -o ./Libs/"+libname+" "+src_path+"/"+src_name).data());
if(rtn != -1 && rtn != 127)
return 0;
else throw "fail to build lib file";
}
/**
lib文件的操作柄
@return 0
*/
int CPart::GetSo(void){
// 读取lib文件
this->handle = dlopen(("Libs/"+libname).data(), RTLD_NOW | RTLD_GLOBAL);
if(this->handle == nullptr) throw "can not open lib file";
// 获得该模块的入口
this->func = (PCSFUNC) dlsym(this->handle, this->name.data());
if(this->func == nullptr) throw "can not get func "+this->name;
// 获得向该模块传入参数的vector的地址
this->libargs_in = (vector<void *> *) dlsym(this->handle, ("__"+name+"_args_in").data());
if(this->libargs_in == nullptr) throw "can not get the address of __"+name+"_args_in";
// 获得该函数传出参数所在的vector的地址
this->libargs_out = (vector<void *> *) dlsym(this->handle, ("__"+name+"_args_out").data());
if(this->libargs_out == nullptr) throw "can not get the address of __"+name+"_args_out";
return 0;
}
CPart::~CPart(){
// 释放储存接口输入参数所占用的内存
for(auto k = 0; k < args_in.size(); k++){
if(fargs_in[k] == 0) delete (int *)(args_in[k]);
else delete (double *)(args_in[k]);
}
// 释放储存接口输出参数所占用的内存
for(auto k = 0; k < args_out.size(); k++){
if(fargs_in[k] == 0) delete (int *)(args_out[k]);
else delete (double *)(args_out[k]);
}
// 停止对lib文件的操作
if(handle != nullptr)
dlclose(handle);
}
/**
@param fargs_in
@param fargs_out
*/
void CPart::setArgsType(vector<int> fargs_in, vector<int> fargs_out){
this->fargs_in = fargs_in;
this->fargs_out = fargs_out;
}
/**
@return SUCCESS
*/
int CPart::Run(void){
// 对计算模块传入参数
unsigned long count = fargs_in.size()-1;
for(auto k = args_in.rbegin(); k != args_in.rend();k++,count--){
if(fargs_in[count] == INT){
@ -58,8 +114,10 @@ int CPart::Run(void){
CPart::addArg(libargs_in, *((double *)(*k)));
}
}
// 执行计算模块
if(func() == SUCCESS){
int count = 0;
//储存计算结果
for(auto k = libargs_out->begin(); k != libargs_out->end();k++,count++){
if(fargs_out[count] == INT){
CPart::addArg(&args_out, *((int *)(*k)));
@ -73,13 +131,21 @@ int CPart::Run(void){
else return -1;
}
/**
*/
void CPart::Clear(void){
for(auto k = 0; k < args_in.size(); k++){
// 释放传入参数所占的空间
for(auto k = args_in.size() - 1; ~k; k--){
if(fargs_in[k] == INT) delete (int *)(args_in[k]);
else delete (double *)(args_in[k]);
args_in.pop_back();
}
for(auto k = 0; k < args_out.size(); k++){
// 释放传出参数所占用的内存空间
for(auto k = args_out.size() - 1; ~k; k--){
if(fargs_in[k] == INT) delete (int *)(args_out[k]);
else delete (double *)(args_out[k]);
args_out.pop_back();
}
}

54
cpart.h
View File

@ -17,64 +17,104 @@
using std::vector;
using std::string;
//声明计算模块的传入与传出参数列表
#define ARGS_DECLAER(name) vector<void *> __##name##_args_in, __##name##_args_out
//声明计算模块的入口
#define PCSFUNC_DEFINE(name) extern "C" int name(void)
#define GET_ARGS(name,type) CPart::popArg<type>(&__##name##_args_in)
#define ADD_ARGS(name,type,value) CPart::addArg<type>(&__##name##_args_out, value);
//从传入参数列表的第一个值,并删除该值
#define POP_ARGS(name,type) GET_ARGS( name ,type)
//向传出参数列表中添加值
#define PUSH_ARGS(name,type,value) ADD_ARGS( name ,type,value)
#define INT 0
#define DOUBLE 1
//调用计算模块成功的返回
#define SUCCESS 0
#define FAIL 1
//调用计算模块失败的返回
#define FAIL -1
typedef int(*PCSFUNC)(void);
class CPart;
//计算模块管理对象间的依赖关系
class Depends{
public:
// 指向依赖的计算模块管理对象的指针
CPart *t_cpart;
// 所依赖的输入参数在计算模块输入参数列表中的序号
vector<int> args;
};
//计算模块管理对象
class CPart{
public:
// 参数形式信息列表
vector<int> fargs_in, fargs_out;
// 参数操纵列表
vector<void *> args_in, args_out;
// lib文件中相关参数操纵列表的地址
vector<void *> *libargs_in,*libargs_out;
// 所依赖的计算对象列表
vector<Depends> depends;
// lib文件中的计算模块的入口地址
int (*func)(void);
// lib文件操作柄
void *handle;
string src_path,name,libname;
// 源文件所在目录
string src_path;
// 计算模块名
string name;
// lib文件名
string libname;
// 源文件名
string src_name;
// 当计算模块随着该工具同时编译时可以直接使用该构造函数
CPart(PCSFUNC func):func(func),handle(nullptr){}
CPart(string src_path,string src_name,string name);
CPart(string name);
// 一般构造函数,计算模块在文件中以源文件的形式独立存在时使用该构造函数
CPart(string src_path,string src_name,string name,bool ffresh = true);
// 析构函数
~CPart();
// 设置输入输出参数形式信息
void setArgsType(vector<int> fargs_in, vector<int> fargs_out);
// 编译源文件
int BuildSo(void);
// 获得lib文件操作柄
int GetSo(void);
// 运行计算模块
int Run(void);
// 清空计算历史记录
void Clear(void);
// 在对象的传入参数列表中添加参数值
template<class T> void addArgsIn(T value){
T *p_value = new T(value);
if(p_value == nullptr) throw "fail to malloc";
args_in.push_back(p_value);
}
// 一般由lib文件中的计算模块调用的向vector中添加参数并分配内存空间而后初始化
template<class T>
static void addArg(vector<void *> *args,T value){
T *p_value = new T(value);
if(p_value == nullptr) throw "fail to malloc";
*p_value = value;
args->push_back(p_value);
}
// 一般由lib文件中的计算模块调用的从vector中获得参数并释放其占用的内存空间而后返回相关值
template<class T>
static T popArg(vector<void *> *args){
if(args == nullptr) throw "the pointer to vector is null";
T *p_value = (T *)args->back();
T value = *p_value;
args->pop_back();
return *p_value;
return value;
}
};

123
net.h
View File

@ -178,130 +178,7 @@ public:
}
};
class CMap{
public:
map<string,CPart *> cparts;
string path;
CMap(string path){
ifstream map;
map.open(path+"/pcs.map");
this->path = path;
if(map.good()){
string line;
map>>line;
if(line == "#PCS"){
BuildCPart(map);
}
map>>line;
if(line == "#DEPEND"){
BuildConnection(map);
}
}
}
void BuildCPart(ifstream &map){
string line;
map>>line;
while(line!="END"){
unsigned long qs = line.find('(',0), qe = line.find(')',0);
string name = line.substr(qs+1,qe-qs-1);
qs = line.find('<',0);
qe = line.find('>',0);
string src_name = line.substr(qs+1,qe-qs-1);
//std::cout<<name<<" "<<src_name<<std::endl;
CPart *ncp = new CPart(path,src_name,name);
this->cparts.insert(pair<string,CPart *>(name,ncp));
vector<int>fargs_in,fargs_out;
map>>line;
if(line[0] == '>'){
fargs_in = BuidArgs(line);
}
map>>line;
if(line[0] == '<'){
fargs_out = BuidArgs(line);
}
ncp->setArgsType(fargs_in, fargs_out);
map>>line;
}
}
vector<int> BuidArgs(string &line){
vector<int> fargs;
unsigned long qs,qe;
qs = line.find('[',0);
qe = line.find(']',0);
unsigned long idx = qs;
while(idx < qe){
unsigned long ts,te;
ts = line.find(':',idx);
te = line.find(',',ts);
if(te == string::npos){
te = qe;
}
string type = line.substr(ts+1,te-ts-1);
if(type == "int")
fargs.push_back(INT);
else if(type == "double")
fargs.push_back(DOUBLE);
idx = te;
}
return fargs;
}
void BuildConnection(ifstream &map){
string line;
map>>line;
while(line != "END"){
unsigned long qs = line.find('(',0), qe = line.find(')',0);
string name = line.substr(qs+1,qe-qs-1);
CPart *p_ncp = cparts.find(name)->second;
unsigned long idx = line.find('{',qe);
unsigned long ss = line.find('}',idx);
unsigned long ts, te;
while(idx+1 < ss){
ts = line.find('(',idx);
te = line.find(']',ts);
if(te == string::npos){
te = ss;
}
string item = line.substr(ts,te-ts+1);
//cout<<item<<endl;
idx = te+1;
p_ncp->depends.push_back(ReadItem(item));
}
map>>line;
}
}
Depends ReadItem(string item){
Depends dep;
unsigned long qs = item.find('(',0), qe = item.find(')',qs);
string name = item.substr(qs+1,qe-qs-1);
dep.t_cpart = cparts.find(name)->second;
unsigned long idx = item.find('[',0),ss = item.find(']',idx);
unsigned long ts, te;
while(idx < ss){
ts = idx;
te = item.find(',',ts+1);
if(te == string::npos){
te = ss;
}
string arg = item.substr(ts+1,te-ts-1);
std::stringstream sstr;
int darg;
sstr<<arg;
sstr>>darg;
dep.args.push_back(darg);
idx = te;
}
return dep;
}
};
class CThread{
public: