c++调用dll动态库

调用dll,首先就有c++windows冲突的故事.
所以,先把障碍解决掉.
首先在库上

用 名字空间 标;
#define NOMINMAX
#include <窗口.h>

去掉min,max不然,折腾.
然后要解决char byte与std::byte的冲突.这里更详细.
cpp上添加:

#define _HAS_STD_BYTE 0
#include <常用>
#include "解库号.cpp"

如下.然后,就可以编译正常了.
我们的库不用写def文件.因为写了,也不知道如何用.不写,也能用得起.而且更爽.
先编译动态库.cl /LD开头.剩余的与编译正常程序一样.
当然,编译之前,要将头文件加上 引出关键字.
引出为__declspec(dllexport),只能加在普通函数上.不能导出模板.
详细加载库代码在这里:

#pragma once
用 名字空间 标;
#define NOMINMAX
#include <窗口.h>
//因为max等冲突了.
//想办法隐藏那几个函数.不然利用不了我的函数库

类 解库号{
    H模块 m;无序映<,>;整 大小=0;:
    解库号():m(空针){}
    ~解库号(){卸载();}
    极 卸载(){//可以手动卸载(m==空针)中 真;
        动 b=释放库(m);(!b)中 假;
        m=空针;中 真;
    }
    极 加载(常 符*l,常 符*y){
        串 a=l,b=y;中 加载(a,b);
    }
    极 加载(&l,&y){//库名,及其<名,号>映射
        m=加载库(l.数据());文件至串整(y,);
        大小=.大小();(空针==m){打印("找不到");中 假;}
        中 真;
    }//名字加编号
    //自然是取函数的意思<型名 T>函数<T>(整 i){//号
        断定(i>=0&&i<大小,"必须在区间");
        动 d=取过程地址(m,(*)(i));
        中 函数<T>((T*)(d));//转为指针
    }
    整 转整(&l){
        动 t=.查找(l);//打印(t->第二);
        断定(t!=.(),"未找到函数");中 t->第二;
    }<型名 T>函数<T>(&l){//号
        中 取<T>(转整(l));
    }<型名 T,型名...O>
    型名 调果型<T,O...>执行(整 i,O&&...o){
        动 f=<T>(i);断定(f!=空针,"找不到");f(前向<O>(o)...);
    }//不折腾,减少不了啥<型名 T,型名...O>
    型名 调果型<T,O...>执行(&l,O&&...o){
        中 执行(转整(l),前向<O>(o)...);
    }
};


当然,这里要感谢祁宇大神的dllparser.
在编译好dll后,用viewapi提取出序号,函数名.其内部用的是utf8格式,转成gbk.然后,自己处理下,搞成函数名,序号格式.
然后整个文件,命名为导出.txt.这样,加载本dll的同时,加载这个导出文件,这样就可以用函数名来取函数了.
最后是测试代码:

#define _HAS_STD_BYTE 0
#include <常用>
#include "解库号.cpp"
//#define NOMINMAX

空 主(){
    //用 B=函数<整(整,整)>;
    //又 整(*B)(整,整);
    解库号 j;j.加载("常用.dll","导出.txt");
    串 d{"符在串"};
    动 t=j.<(,&)>(d);
    //注意,连&都要加上,不然,要报错.
    //动 b=(B*)GetProcAddress(h,(符*)(2));
    //用序号
    符 c{'a'};串 b{"bat"};
    极 i=t(c,b);
    //极 i=t(b);
    输出<<i;
}

注意,在函数<T>T中,连&也要加上.不然要报错.
还有返回类型也要一致.不然要报错.

posted @ 2020-11-12 11:23  zjh6  阅读(54)  评论(0)    收藏  举报  来源