diff --git a/Net.xcodeproj/project.pbxproj b/Net.xcodeproj/project.pbxproj index e5472d8..0a8cee4 100644 --- a/Net.xcodeproj/project.pbxproj +++ b/Net.xcodeproj/project.pbxproj @@ -50,6 +50,8 @@ 92A1F29F21F1663300340EFA /* memory.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = memory.cpp; sourceTree = ""; }; 92A1F2A021F1663300340EFA /* memory.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = memory.h; sourceTree = ""; }; 92A1F2A421F21DC700340EFA /* a.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = a.cpp; path = build/Debug/PCS/a.cpp; sourceTree = ""; }; + 92A1F2A621F2412500340EFA /* compute.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = compute.h; sourceTree = ""; }; + 92A1F2A721F242C900340EFA /* memory_type.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = memory_type.h; sourceTree = ""; }; 92D6CE6721EE4920005AEF3B /* server.cpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.cpp; path = server.cpp; sourceTree = ""; }; 92D6CE6821EE4920005AEF3B /* server.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = server.h; sourceTree = ""; }; /* End PBXFileReference section */ @@ -111,6 +113,8 @@ 9221DA0F21EB5FB8007310A7 /* net.h */, 92D6CE6821EE4920005AEF3B /* server.h */, 92A1F29C21F0C67600340EFA /* type.h */, + 92A1F2A621F2412500340EFA /* compute.h */, + 92A1F2A721F242C900340EFA /* memory_type.h */, ); name = include; sourceTree = ""; diff --git a/cmap.cpp b/cmap.cpp index da4d160..5e73230 100644 --- a/cmap.cpp +++ b/cmap.cpp @@ -46,7 +46,7 @@ void CMap::BuildCPart(ifstream &map){ string src_name = line.substr(qs+1,qe-qs-1); // 根据以上信息构造计算管理结构对象 - CPart *ncp = new CPart(path,src_name,name); + CPart *ncp = new CPart(path,"./Lib",src_name,name); // 在列表中加入该对象 this->cparts.insert(pair(name,ncp)); diff --git a/compute.h b/compute.h new file mode 100644 index 0000000..3344092 --- /dev/null +++ b/compute.h @@ -0,0 +1,83 @@ +// +// compute.h +// Net +// +// Created by 胡一兵 on 2019/1/19. +// Copyright © 2019年 Bakantu. All rights reserved. +// + +#ifndef compute_h +#define compute_h + +#include "memory_type.h" +#include +using std::vector; + +//声明计算模块的传入与传出参数列表 +#define ARGS_DECLAER(name) vector __##name##_args_in, __##name##_args_out +//声明计算模块的入口 +#define PCSFUNC_DEFINE(name) extern "C" int name(void) + +//合并计算模块入口函数定义及参数入口与出口操作柄声明 +#define _PCSFUNC(name) ARGS_DECLAER(name); \ +PCSFUNC_DEFINE(name) + +//用户获得计算过程入口操作柄 +#define ARGS_IN(name) __##name##_args_in +//用户获得计算过程出口操作柄 +#define ARGS_OUT(name) __##name##_args_out + +//调用成功的返回 +#define SUCCESS 0 +//调用失败的返回 +#define FAIL -1 + +class LibArgsTransfer{ + friend class CPart; + // 计算过程参数入口或出口操作柄 + vector *args = nullptr; + + // 计算模块向入口添加自定义指针参数 + void addArgPtr(int size, void *p_arg); + // 清空参数入口与出口 + void clear(void); + + LibArgsTransfer(); +public: + // 计算过程构造该类的唯一构造函数 + LibArgsTransfer(vector &args){ + this->args = &args; + } + // 计算过程从入口处获得参数 + template + T get_arg(int idx){ + T *pvle = (T *)(*args)[idx].pvle; + // 检查用户所提供的类型与入口该位置的参数大小是否匹配 + if((*args)[idx].size == sizeof(T)) return *pvle; + else throw "arg size conflict"; + } + // 计算过程从入口获得自定义指针参数 + template + T *get_arg_ptr(int idx){ + T *pvle = (*args)[idx].pvle; + return pvle; + } + // 计算过程向出口末尾添加自定义指针参数 + void push_arg_ptr(int size, void *p_arg){ + block_info pbifo(size,p_arg); + args->push_back(pbifo); + } + // 计算过程向出口末尾添加参数 + template + void push_arg(T arg){ + T *p_arg = (T *)malloc(sizeof(T)); + *p_arg = arg; + block_info pbifo(sizeof(T),p_arg); + args->push_back(pbifo); + } + ~LibArgsTransfer(){ + //clear(); + } +}; + +#endif /* compute_h */ diff --git a/cpart.cpp b/cpart.cpp index 3da483c..60cd75b 100644 --- a/cpart.cpp +++ b/cpart.cpp @@ -9,43 +9,80 @@ #include "memory.h" #include "cpart.h" + /** - 设置计算模块的接口形式 - - @param src_path 源文件所在的目录地址 - @param src_name 源文件的名字 - @param name 计算模块的名字 - @param ffresh 每次建立该结构都重新编译一次源文件 + 计算模块类构造函数 + + @param t_srcpath 源文件路径 + @param t_libpath 生成的动态链接库路径 + @param t_srcname 源文件名 + @param t_name 模块入口函数名 + @param ffresh 是否强制刷新动态链接库 */ -CPart::CPart(string src_path,string src_name,string name,bool ffresh):func(nullptr),handle(nullptr){ - this->src_path = src_path; - this->name = name; +CPart::CPart(string t_srcpath,string t_libpath,string t_srcname,string t_name,bool ffresh):func(nullptr),handle(nullptr){ - this->src_name = src_name; -// 去掉源文件的后缀 - unsigned long qp = src_name.find(".",0); - if(qp == string::npos){ - qp = src_name.size()-1; + this->name = t_name; + +// 修饰源文件路径名 + t_srcpath.erase(t_srcpath.find_last_not_of(" ")+1); + if(t_srcpath.back() == '/') t_srcpath.pop_back(); + this->src_path = t_srcpath; + +// 除去源文件名两端的空格 + t_srcname.erase(t_srcname.find_last_not_of(" ")+1,t_srcname.length()); + t_srcname.erase(0,t_srcname.find_first_not_of(" ")); + +// 检查源文件名是否合法 + unsigned long qpidx = t_srcname.find(".cpp",0); + if(qpidx == string::npos) throw "source file's name illegal(.cpp)"; + for (auto c : t_srcname.substr(0,qpidx)) { + if(isalnum(c) || c == '_'); + else throw "source file's name has illegal char"; } -// 生成lib文件的文件名 - string t_libname = "lib"+src_name.substr(0,qp)+".so"; - this->libname = t_libname; + + // 检查源文件文件是否存在且可写 + if(access((src_path+"/"+t_srcname).data(), W_OK) == -1) throw "source file's state abnormal"; + this->src_name = t_srcname; + + +// 根据合法的源文件名生成lib文件的文件名 + string t_libname = "lib"+src_name.substr(0,qpidx)+".so"; + this->lib_name = t_libname; + +// 修饰动态链接库路径名 + t_libpath.erase(t_libpath.find_last_not_of(" ")+1); + if(t_libpath.back() == '/') t_libpath.pop_back(); + +// 检查动态链接库生成目录是否存在且可写 + if(access((t_libpath).data(), W_OK) == -1) throw "library path is abnormal"; + this->lib_path = t_libpath; + +// 检查模块入口函数名是否含有非法字符 + for (auto c : t_name) { + if(isalnum(c) || c == '_'); + else throw "PCSFUNC's name has illegal char"; + } + this->name = t_name; + // 如果lib文件存在且不要求每次建立该结构都重新编译一次源文件的话就不执行编译 - if(!~access(("Libs/"+t_libname).data(), F_OK) || ffresh){ + if(!~access((lib_path+lib_name).data(), F_OK) || ffresh){ +// 编译源文件生成动态链接库 BuildSo(); - GetSo(); +// 获得动态链接库的操作柄 + GetSoHandle(); } } /** - 执行源文件编译操作,生成动态链接库 + 执行源文件编译操作,在指定位置生成动态链接库 @return 执行成功将返回0 */ int CPart::BuildSo(void){ - int rtn = system(("g++ -fPIC -shared -std=c++11 -o ./Libs/"+libname+" "+src_path+"/"+src_name).data()); + int rtn = system(("g++ -fPIC -shared -std=c++11 -o "+lib_path+"/"+lib_name+" "+src_path+"/"+src_name).data()); +// 检测命令执行情况 if(rtn != -1 && rtn != 127) return 0; else throw "fail to build lib file"; @@ -53,42 +90,40 @@ int CPart::BuildSo(void){ /** - 获得lib文件的操作柄,并获得计算模块的入口地址及传入传出参数列表的地址。 + 获得动态链接库的操作柄,并获得传入参数的操作柄及传出参数的操作柄。 @return 执行成功则返回0 */ -int CPart::GetSo(void){ - // 读取lib文件 - this->handle = dlopen(("Libs/"+libname).data(), RTLD_NOW | RTLD_LOCAL); - if(this->handle == nullptr) throw "can not open lib file"; - // 获得该模块的入口 +int CPart::GetSoHandle(void){ +// 检查动态链接库生成目录是否存在且可读 + if(access((lib_path).data(), R_OK) == -1) throw "library not found"; +// 获得动态链接库的操作柄 + this->handle = dlopen((lib_path+"/"+lib_name).data(), RTLD_NOW | RTLD_LOCAL); + if(this->handle == nullptr) throw "can not open library"; +// 获得该模块的入口 this->func = (PCSFUNC) dlsym(this->handle, this->name.data()); if(this->func == nullptr) throw "can not get func "+this->name; - // 获得向该模块传入参数的vector的地址 +// 获得向该模块传入参数的操作柄 this->libargs_in.args = (vector *) dlsym(this->handle, ("__"+name+"_args_in").data()); - if(this->libargs_in.args == nullptr) throw "can not get the address of __"+name+"_args_in"; - // 获得该函数传出参数所在的vector的地址 + if(this->libargs_in.args == nullptr) throw "can not get the HANDLE to PUSH args"; +// 获得获取该模块传出参数的操作柄 this->libargs_out.args = (vector *) dlsym(this->handle, ("__"+name+"_args_out").data()); - if(this->libargs_out.args == nullptr) throw "can not get the address of __"+name+"_args_out"; + if(this->libargs_out.args == nullptr) throw "can not get the HANDLE to GET args"; + return 0; } CPart::~CPart(){ -// 释放储存接口输入参数所占用的内存 - for(auto arg : args_in) main_pool.b_free(arg); -// 释放储存接口输出参数所占用的内存 - for(auto arg : args_out) main_pool.b_free(arg); -// 停止对lib文件的操作 - if(handle != nullptr) - dlclose(handle); + Clear(); + if(handle != nullptr) dlclose(handle); } /** - 设置计算模块的接口形式 + 设置计算模块的参数格式便于检查 - @param fargs_in 调用接口形式 - @param fargs_out 输出接口形式 + @param fargs_in 输入参数格式 + @param fargs_out 输出参数格式 */ void CPart::setArgsType(vector fargs_in, vector fargs_out){ this->fargs_in = fargs_in; @@ -96,23 +131,27 @@ void CPart::setArgsType(vector fargs_in, vector fargs_out){ } /** - 向计算模块传入参数,并运行计算模块,而后获得计算结果 + 利用传入操作柄向计算模块入口传入参数,并运行计算模块,而后利用传出操作柄从出口获得传出参数 - @return 如果执行成功则返回SUCCESS + @return 如果计算过程执行成功则返回SUCCESS */ int CPart::Run(void){ if(func == nullptr) throw "func is nullptr"; + +// 检查传入参数缓冲区是否正确初始化 + if(args_in.size() != fargs_in.size()) throw "input arg buff is't correctly init"; // 对计算模块传入参数 for(auto arg : args_in) libargs_in.addArgPtr(main_pool.size(arg), arg); -// 执行计算模块 + +// 执行计算过程 if(func() == SUCCESS){ -//储存计算结果 +// 从出口获得传出参数到传出参数缓冲区 for(auto libarg : *libargs_out.args){ -// 获得内存块的访问量 void *arg = main_pool.bp_malloc(libarg.size, libarg.pvle); args_out.push_back(arg); } +// 清空出口数据 libargs_out.clear(); return SUCCESS; } @@ -121,13 +160,36 @@ int CPart::Run(void){ /** - 清空上一次的计算参数及结果数据,并释放相关内存空间 + 清空传入参数缓冲区与传出参数缓冲区 */ void CPart::Clear(void){ -// 释放传入参数所占的空间 +// 清空传入参数缓冲区 for(auto arg : args_in) main_pool.b_free(arg); args_in.clear(); -// 释放传出参数所占用的内存空间 +// 清空传出参数缓冲区 for(auto arg : args_out) main_pool.b_free(arg); args_out.clear(); } + +void CPart::AddCPArgsIn(void *arg){ + void *p_value = main_pool.b_get(arg); + if(p_value == nullptr) throw "information lost"; + args_in.push_back(p_value); +} + +void LibArgsTransfer::addArgPtr(int size, void *p_arg){ + void *pc_arg = malloc(size); + memcpy(pc_arg, p_arg, size); + block_info pbifo(size,pc_arg); + args->push_back(pbifo); +} + +void LibArgsTransfer::clear(void){ + for(auto arg : *args) + free(arg.pvle); + args->clear(); +} + +LibArgsTransfer::LibArgsTransfer(){ + +} diff --git a/cpart.h b/cpart.h index 4a598da..51b51a8 100644 --- a/cpart.h +++ b/cpart.h @@ -11,30 +11,13 @@ #include "type.h" #include "memory.h" - -//声明计算模块的传入与传出参数列表 -#define ARGS_DECLAER(name) vector __##name##_args_in, __##name##_args_out -//声明计算模块的入口 -#define PCSFUNC_DEFINE(name) extern "C" int name(void) - -#define _PCSFUNC(name) ARGS_DECLAER(name); \ -PCSFUNC_DEFINE(name) - -//从传入参数列表的第一个值,并删除该值 -#define ARGS_IN(name) __##name##_args_in -//向传出参数列表中添加值 -#define ARGS_OUT(name) __##name##_args_out +#include "compute.h" //整型 #define INT 0 //浮点型 #define DOUBLE 1 -//调用计算模块成功的返回 -#define SUCCESS 0 -//调用计算模块失败的返回 -#define FAIL -1 - //计算模块入口函数类型 typedef int(*PCSFUNC)(void); @@ -49,100 +32,49 @@ public: vector args; }; -class LibArgsTransfer{ -public: - vector *args = nullptr; - LibArgsTransfer(vector &args){ - this->args = &args; - } - LibArgsTransfer(){ - - } - void addArgPtr(int size, void *p_arg){ - void *pc_arg = malloc(size); - memcpy(pc_arg, p_arg, size); - block_info pbifo(size,pc_arg); - args->push_back(pbifo); - } - template - T getArg(int idx){ - T *pvle = (T *)(*args)[idx].pvle; - if((*args)[idx].size == sizeof(T)) return *pvle; - else throw "arg size conflict"; - } - template - T *getArgPtr(int idx){ - T *pvle = (*args)[idx].pvle; - return pvle; - } - void LibAddArgPtr(int size, void *p_arg){ - block_info pbifo(size,p_arg); - args->push_back(pbifo); - } - template - void LibAddArg(T arg){ - T *p_arg = (T *)malloc(sizeof(T)); - *p_arg = arg; - block_info pbifo(sizeof(T),p_arg); - args->push_back(pbifo); - } - void clear(void){ - for(auto arg : *args) - free(arg.pvle); - args->clear(); - } - ~LibArgsTransfer(){ - //clear(); - } -}; - //计算模块类 class CPart{ public: -// 参数形式信息列表 +// 参数格式信息列表 vector fargs_in, fargs_out; -// 参数操纵列表 +// 输入参数与输出参数缓冲区 vector args_in, args_out; -// lib文件中相关参数操纵列表的地址 +// 计算过程入口与出口管理类 LibArgsTransfer libargs_in, libargs_out; -// 所依赖的计算对象列表 +// 依赖计算对象列表 vector depends; -// lib文件中的计算模块的入口地址 - int (*func)(void); -// lib文件操作柄 - void *handle; +// 计算过程的入口函数的地址 + int (*func)(void) = nullptr; +// 动态链接库操作柄 + void *handle = nullptr; // 源文件所在目录 string src_path; // 计算模块名 string name; -// lib文件名 - string libname; +// 动态链接库路径 + string lib_path; +// 动态链接库名 + string lib_name; // 源文件名 string src_name; -// 一般构造函数,计算模块在文件中以源文件的形式独立存在时使用该构造函数 - CPart(string src_path,string src_name,string name,bool ffresh = true); +// 唯一的构造函数 + CPart(string src_path,string lib_path,string src_name,string name,bool ffresh = true); // 析构函数 ~CPart(); -// 设置输入输出参数形式信息 +// 设置输入输出参数格式信息列表 void setArgsType(vector fargs_in, vector fargs_out); // 编译源文件 int BuildSo(void); -// 获得lib文件操作柄 - int GetSo(void); -// 运行计算模块 +// 获得动态链接库操作柄 + int GetSoHandle(void); +// 运行计算过程 int Run(void); -// 清空计算历史记录 +// 清空传入传出参数缓冲区 void Clear(void); - -// 在对象的传入参数列表中添加参数值 - void AddCPArgsIn(void *arg){ - void *p_value = main_pool.b_get(arg); - if(p_value == nullptr) throw "information lost"; - args_in.push_back(p_value); - } +// 在传入参数缓冲区中添加参数 + void AddCPArgsIn(void *arg); }; - #endif /* cpart_h */ diff --git a/main.cpp b/main.cpp index cec6bd8..b7c459d 100644 --- a/main.cpp +++ b/main.cpp @@ -26,7 +26,7 @@ void CPMT(void){ int main(void){ initClock(); - CPart ncp("./PCS","a.cpp","A"); + CPart ncp("./PCS","./Libs","a.cpp","A"); void *a = main_pool.bv_malloc(2.0); void *b = main_pool.bv_malloc(3.5); void *c = main_pool.bv_malloc(5); diff --git a/memory.h b/memory.h index 9c0d20a..e93adb4 100644 --- a/memory.h +++ b/memory.h @@ -10,20 +10,7 @@ #define memory_h #include "type.h" - -struct block_info{ - uint32_t size = 0; - int lock = 0; - bool pted = false; - void *pvle = nullptr; - block_info(uint32_t size,void *pvle){ - this->size = size; - this->pvle = pvle; - } - block_info(){ - - } -}; +#include "memory_type.h" class BlocksPool{ // 内存块表 diff --git a/memory_type.h b/memory_type.h new file mode 100644 index 0000000..cca3748 --- /dev/null +++ b/memory_type.h @@ -0,0 +1,28 @@ +// +// memory_type.h +// Net +// +// Created by 胡一兵 on 2019/1/19. +// Copyright © 2019年 Bakantu. All rights reserved. +// + +#ifndef memory_type_h +#define memory_type_h + +#include + +struct block_info{ + uint32_t size = 0; + int lock = 0; + bool pted = false; + void *pvle = nullptr; + block_info(uint32_t size,void *pvle){ + this->size = size; + this->pvle = pvle; + } + block_info(){ + + } +}; + +#endif /* memory_type_h */ diff --git a/type.h b/type.h index ff106d1..dd939f0 100644 --- a/type.h +++ b/type.h @@ -24,6 +24,7 @@ #include #include #include +#include #include #include #include