当前位置: 首页 > news >正文

网页设计尺寸规范psseo营销培训

网页设计尺寸规范ps,seo营销培训,电商运营工资一般多少钱一个月,vscode 网站开发教程本文讲述C如何直接调用动态库dll或者so中的函数。 首先我们准备一个被调用库#xff0c;这个库里面有两个函数#xff0c;分别是C98 与 C11 下的#xff0c;名称是run2和run1。 被调用库 相关介绍请看之前的文章《函数指针与库之间的通信讲解》。 //dll_ex_im.h #ifndef…本文讲述C如何直接调用动态库dll或者so中的函数。 首先我们准备一个被调用库这个库里面有两个函数分别是C98 与 C11 下的名称是run2和run1。 被调用库 相关介绍请看之前的文章《函数指针与库之间的通信讲解》。 //dll_ex_im.h #ifndef __DLL_EX_IM_H__ #define __DLL_EX_IM_H__ #include functional #include string #include iostream #include thread #include chrono #ifdef _WINDOWS #ifdef DLLProvider #define DLL_EXPORT_IMPORT __declspec(dllexport) #else #define DLL_EXPORT_IMPORT __declspec(dllimport) #endif #else #define DLL_EXPORT_IMPORT __attribute__((visibility(default))) #endif//typedef class DLL_EXPORT_IMPORT std::function void(std::string) output_to_caller; DLL_EXPORT_IMPORT void run1(int a, std::function void(std::string) output); DLL_EXPORT_IMPORT void run2(int a, void(*output)(std::string));#endif //__DLL_EX_IM_H__//dll_ex_im.cpp #include dll_ex_im.hvoid run1(int a, std::function void(std::string) output) {std::cout run1 std::endl;std::cout got parametrer: a std::endl;std::cout return signal: std::endl;while (true) {output(run1: std::to_string(a));std::this_thread::sleep_for(std::chrono::milliseconds(1000));} }void run2(int a, void(*output)(std::string)) {std::cout run2 std::endl;std::cout got parametrer: a std:bian编译一下出来的动态库在Windows下是Reflection-DLL_TEST.dll在Linux下是libReflection-DLL_TEST.so。 Windows下直接调用 我们用BinaryViewer这款二进制查看器看看函数run1和run2在Reflection-DLL_TEST.dll长什么样子。 查找函数run1的位置 找到三个位置前两个应该都是函数的名称指引知道的同学可以介绍下前两个是做啥的。 第三个是run1函数的地址 我把这个run1地址写下来 ?run1YAXHV?$function$$A6AXV?$basic_stringDU?$char_traitsDstdV?$allocatorD2stdZstdZ原来的函数run1长这样 void run1(int a, std::function void(std::string) output);查找函数run2的位置 找到三个位置前两个应该都是函数的名称指引知道的同学可以介绍下前两个是做啥的。 第三个是run2函数的地址 我把这个run2地址写下来 ?run2YAXHP6AXV?$basic_stringDU?$char_traitsDstdV?$allocatorD2stdZZ原来的函数run2长这样 void run2(int a, void(*output)(std::string));地址解释 以上run1和run2函数在dll二进制文件中的地址是一个经过VS C编译器名称修饰后的函数名这种修饰是编译器用来区分具有相同名称但不同参数或返回类型的函数的方法。 由于我不是做编译器的下面我用聊天机器人查了一下仅给出以上run1函数地址的解释 ?run1这是函数名run1的开头部分其中?和是Microsoft编译器特有的名称修饰符号。 YAXH这表示函数的返回类型和参数类型。在这个例子中Y 表示返回类型为 voidAX 通常表示没有通过值传递的参数但在这个特定情况下由于后面有V它实际上表示有一个通过引用或指针传递的参数H 是参数列表的开始。不过这里的AX和H的具体含义可能因编译器的具体实现而略有不同重要的是理解整体结构。 V这表示接下来的部分是一个通过引用或指针传递的参数。 ?$function…std这是对 std::function 模板的修饰表示其中省略号…代表模板参数的具体类型即 void(std::string)。 KaTeX parse error: Cant use function $ in math mode at position 7: A6AXV?$̲basic_string..…A6 是与调用约定相关的可能是 __cdecl 的某种变体但具体取决于编译器和平台AXV 表示函数接受一个参数V 表示通过引用或指针?$basic_string…stdZ 是对 std::string 类型的修饰表示。 Windows调用程序 #include iostream //#include list #include functional #ifdef _WINDOWS #include shlwapi.h #include Psapi.h #include codecvt #else #include dlfcn.h #include codecvt #endifvoid callback(std::string info) {std::cout info std::endl; }void Run1(const std::string dllpath, const std::string initFuncName) {std::string funName initFuncName; #ifdef _WINDOWStypedef void(_stdcall* pfnInitPlugin) (int, std::function void(std::string));funName ? funName YAXHV?$function$$A6AXV?$basic_stringDU?$char_traitsDstdV?$allocatorD2stdZstdZ;auto module LoadLibrary(dllpath.c_str());//寻找初始化函数并执行pfnInitPlugin initfunc (pfnInitPlugin)GetProcAddress(module, funName.c_str());if (initfunc){//常规方式//std::function void(std::string) cb callback;//initfunc(4, cb);//lambda方式initfunc(4, [](std::string info) {std::cout info std::endl; });}else {std::cout 未找到函数地址 std::endl;} #elsetypedef void(__attribute__((__stdcall__))* pfnInitPlugin) (int, std::function void(std::string));funName _Z22 funName v;auto dp dlopen(p.c_str(), RTLD_LAZY | RTLD_GLOBAL);if (dp){pfnInitPlugin initfunc (pfnInitPlugin)dlsym(dp, funName.c_str());if (initfunc){initfunc(4, [](std::string info) {std::cout info std::endl;});}//dlclose(dp);}else {std::cout 未找到函数地址 std::endl;} #endif }void Run2(const std::string dllpath, const std::string initFuncName) {std::string funName initFuncName; #ifdef _WINDOWStypedef void(_stdcall* pfnInitPlugin) (int, void(*output)(std::string));//run1funName ? funName YAXHP6AXV?$basic_stringDU?$char_traitsDstdV?$allocatorD2stdZZ;auto module LoadLibrary(dllpath.c_str());//寻找初始化函数并执行pfnInitPlugin initfunc (pfnInitPlugin)GetProcAddress(module, funName.c_str());if (initfunc){//void(*cb)(std::string);//cb callback;//initfunc(4, cb);initfunc(4, [](std::string info) {std::cout info std::endl;});}else {std::cout 未找到函数地址 std::endl;} #elsetypedef void(__attribute__((__stdcall__))* pfnInitPlugin) (int, void(*output)(std::string));funName _Z22 funName v;auto dp dlopen(p.c_str(), RTLD_LAZY | RTLD_GLOBAL);if (dp){pfnInitPlugin initfunc (pfnInitPlugin)dlsym(dp, funName.c_str());if (initfunc){initfunc(4, [](std::string info) {std::cout info std::endl;});}//dlclose(dp);}else {std::cout 未找到函数地址 std::endl;} #endif }int main(int argc, char* argv[]) {std::string argv1 argv[1];if (argc 2 argv1 -h){std::cout 用法\n【exe-name】【dll-path】【func-name】 std::endl;return 0;}if (argc ! 3){std::cerr 传入的参数数量不对应该是俩检查检查 std::endl;return -1;}std::string dllPath argv[1];if (dllPath.find(.dll) dllPath.npos){std::cerr 传入的文件没有dll检查检查 std::endl;return -1;}std::string argv2 argv[2];if (argv2 run1){Run1(argv[1], run1);}else if (argv2 run2) {Run2(argv[1], run2);}else {std::cerr 传入的函数名既不是 run1 也不是 run2 检查检查 std::endl;return -1;}return 0; }在Windows下核心代码是下面这几句 typedef void(_stdcall* pfnInitPlugin) (int, std::function void(std::string));//run1funName ? funName YAXHV?$function$$A6AXV?$basic_stringDU?$char_traitsDstdV?$allocatorD2stdZstdZ;auto module LoadLibrary(dllpath.c_str());//寻找初始化函数并执行pfnInitPlugin initfunc (pfnInitPlugin)GetProcAddress(module, funName.c_str());if (initfunc){//常规方式//std::function void(std::string) cb callback;//initfunc(4, cb);//lambda方式initfunc(4, [](std::string info) {std::cout info std::endl; });}else {std::cout 未找到函数地址 std::endl;}程序读入动态库通过函数在动态库中的地址进行直接调用。 下面是调用结果 Linux下直接调用 我们用BinaryViewer这款二进制查看器看看函数run1和run2在libReflection-DLL_TEST.so长什么样子。 查找函数run1的位置 找到4个位置前两个应该都是函数的名称指引知道的同学可以介绍下前3个是做啥的。 第4个是run1函数的地址 我把这个run1地址写下来 _Z4run1iSt8functionIFvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEE原来的函数run1长这样 void run1(int a, std::function void(std::string) output);查找函数run2的位置 找到4个位置前两个应该都是函数的名称指引知道的同学可以介绍下前3个是做啥的。 第4个是run2函数的地址 我把这个run2地址写下来 _Z4run2iPFvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE原来的函数run2长这样 void run2(int a, void(*output)(std::string));地址解释 以上run1和run2函数在so二进制文件中的地址是一个由 GCC编译器生成的 mangled修饰名称。这种名称用于在编译后的代码中唯一标识函数、变量等符号同时包含类型信息。Mangled 名称对于人类来说通常是不直观的但它们对于编译器和链接器来说是必要的以确保在复杂的程序中正确地解析和链接符号。 由于我不是做编译器的下面我用聊天机器人查了一下仅给出以上run1函数地址的解释 _Z 前缀是 GCC 编译器用于 mangled 名称的标识。 4run1i 部分是函数名称的编码其中 run 是函数名1 表示该函数接受一个参数i 表示该参数的类型在这个上下文中它实际上是指接下来的类型信息而不是直接的类型。 St8functionIFvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEE 是参数类型的 mangled 表示。这个类型是一个 std::function它包装了一个可调用对象该对象接受一个 std::string 类型的参数没有返回值因为 Fv 表示一个函数类型没有返回类型。 St8function 表示 std::function。 IFv 表示一个函数F没有返回值v即 void并且接下来是参数类型。 NSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEE 是 std::__cxx11::basic_stringchar, std::char_traits, std::allocator 的 mangled 表示即 std::string。 Linux调用程序 #include iostream //#include list #include functional #ifdef _WINDOWS #include shlwapi.h #include Psapi.h #include codecvt #else #include dlfcn.h #include codecvt #endifvoid callback(std::string info) {std::cout info std::endl; }void Run1(const std::string dllpath, const std::string initFuncName) {std::string funName initFuncName; #ifdef _WINDOWStypedef void(_stdcall* pfnInitPlugin) (int, std::function void(std::string));funName ? funName YAXHV?$function$$A6AXV?$basic_stringDU?$char_traitsDstdV?$allocatorD2stdZstdZ;auto module LoadLibrary(dllpath.c_str());//寻找初始化函数并执行pfnInitPlugin initfunc (pfnInitPlugin)GetProcAddress(module, funName.c_str());if (initfunc){//常规方式//std::function void(std::string) cb callback;//initfunc(4, cb);//lambda方式initfunc(4, [](std::string info) {std::cout info std::endl; });}else{std::coutnot find function namestd::endl;} #elsetypedef void(* pfnInitPlugin) (int, std::function void(std::string));funName _Z4 funName iSt8functionIFvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEE;auto dp dlopen(dllpath.c_str(), RTLD_LAZY | RTLD_GLOBAL);if (dp){pfnInitPlugin initfunc (pfnInitPlugin)dlsym(dp, funName.c_str());if (initfunc){initfunc(4, [](std::string info) {std::cout info std::endl;});}dlclose(dp);}else{std::coutnot find function namestd::endl;} #endif }void Run2(const std::string dllpath, const std::string initFuncName) {std::string funName initFuncName; #ifdef _WINDOWStypedef void(_stdcall* pfnInitPlugin) (int, void(*output)(std::string));funName ? funName YAXHP6AXV?$basic_stringDU?$char_traitsDstdV?$allocatorD2stdZZ;auto module LoadLibrary(dllpath.c_str());//寻找初始化函数并执行pfnInitPlugin initfunc (pfnInitPlugin)GetProcAddress(module, funName.c_str());if (initfunc){//常规方式//void(*cb)(std::string);//cb callback;//initfunc(4, cb);//lambda方式initfunc(4, [](std::string info) {std::cout info std::endl;});}else{std::coutnot find function namestd::endl;} #elsetypedef void(* pfnInitPlugin) (int, void(*output)(std::string));funName _Z4 funName iPFvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEE;auto dp dlopen(dllpath.c_str(), RTLD_LAZY | RTLD_GLOBAL);if (dp){pfnInitPlugin initfunc (pfnInitPlugin)dlsym(dp, funName.c_str());if (initfunc){initfunc(4, [](std::string info) {std::cout info std::endl;});}dlclose(dp);}else{std::coutnot find function namestd::endl;} #endif }int main(int argc, char* argv[]) {//C 98//Lambda回调函数//Run1(./Reflection-DLL_TEST.dll,run1);std::string argv1 argv[1];if (argc 2 argv1 -h){std::cout 用法\n【exe-name】【dll-path】【func-name】 std::endl;return 0;}if (argc ! 3){std::cerr 传入的参数数量不对应该是俩检查检查 std::endl;return -1;}std::string dllPath argv[1];if (dllPath.find(.so) dllPath.npos){std::cerr 传入的文件没有so检查检查 std::endl;return -1;}std::string argv2 argv[2];if (argv2 run1){Run1(argv[1], run1);}else if (argv2 run2) {Run2(argv[1], run2);}else {std::cerr 传入的函数名既不是 run1 也不是 run2 检查检查 std::endl;return -1;}//system(pause);return 0; } 在Linux下核心代码是下面这几句 typedef void(* pfnInitPlugin) (int, std::function void(std::string));funName _Z4 funName iSt8functionIFvNSt7__cxx1112basic_stringIcSt11char_traitsIcESaIcEEEEE;auto dp dlopen(dllpath.c_str(), RTLD_LAZY | RTLD_GLOBAL);if (dp){pfnInitPlugin initfunc (pfnInitPlugin)dlsym(dp, funName.c_str());if (initfunc){initfunc(4, [](std::string info) {std::cout info std::endl;});}dlclose(dp);}else{std::coutnot find function namestd::endl;}程序读入动态库通过函数在动态库中的地址进行直接调用。 下面是调用结果
http://www.dnsts.com.cn/news/921.html

相关文章:

  • 公司资质查询官方网站怎么免费制作网页
  • 网站代码怎么改国内网站建设公司
  • 广州哪里做公司网站号网络推广外包要多少钱
  • 做优化网站多少钱东莞做网站seo
  • 昆山品牌设计公司营销型网站建设优化建站
  • 电脑上如何做网站宣传什么是seo优化推广
  • 碑林区营销型网站建设软文营销的技巧
  • 网站标签优化怎么做移动端排名优化软件
  • 学校网站建设目的是什么意思网络营销工具的特点
  • wordpress博客空间百度快照优化seo
  • 吉林大学建设工程学院官方网站竞价推广套户渠道商
  • 有没有什么做h5的网站营销网站类型
  • 沈阳企业网站2023年最新时政热点
  • 电子商务网站建设规划书四大营销策略
  • ps设计网站步骤舆情报告
  • 网站建设的违约责任制作网站平台
  • 郑州企业网站制作公司河南网络推广那家好
  • 苏州哪家做网站好些建站为应用技术
  • kali做钓鱼网站搜索引擎营销的实现方法有
  • 麟游做网站腾讯企业邮箱登录入口
  • 织梦手机网站有广告环球网广东疫情最新消息
  • 手机下载视频网站模板nba最新新闻
  • 龙之向导外贸专区潍坊网站建设seo
  • 泉州seo建站免费信息推广平台
  • 做三折页的网站国际实时新闻
  • 不同网站的主机和域名南安网站建设
  • 新开传奇网站大全seo到底是做什么的
  • 网站切换语言怎么做泉州百度首页优化
  • 贵州建网站360免费建站官网
  • 网站做竞价优化阿里云网站搭建