64位程序调用32位dll方法
1、谏言
最近接入一个nfc卡程序包,发现了一个问题:
由于我们现在的操作系统都已经64位了,而我们开发的程序自然也是64位的,虽然说64位操作系统上可以运行32位程序,
但是我们开发就避免不了要调用各种第三方库,而这个nfc库巧了,他是远古遗老只有32位的dll,
我们要知道64位程序是不能调用32位dll的(静态库更是不行),问题到这似乎出现的坏味道。
还好 互联网大佬 告诉我们可以通过 IPC (进程间通信)也就是64位程序 与 32位程序 通过进程通讯手段进行变相的调用
这就很多方法了 比如 tcp、udp、共享内存等
不过我们现在要用的是另一个东西
微软的com/ATL项目
这个的说法是可以直接像调用dll函数一样,只需要在操作系统的注册表中进行注册
感觉比传统的IPC方便了很多
2、ATL项目
2.1、创建
选择ATL项目 或者 从搜索中查找
比如项目名称叫 ATL01
这里动态链接库.dll、可执行文件.exe、服务.exe
目前我并不清楚区别 我们这里选择可执行文件exe
2.2、添加ATL支持
右键鼠标点击第一个ATL01的解决方案
添加 --> 新建项–>ATL–>ATL简单对象
随便来个名字 如 ATLtest 点击添加
看项目中需要包含ATL支持
我们再次来到
添加 --> 新建项–>ATL页面
发现没 这里有一个叫ATL支持的 选择添加
然后我们接着添加ATL简单对象 发现还是一样的问题
2.3、添加ATL简单对象
我们需要生成一下解决方案
目前为止我们先切换一下编译架构 我们需要切换为32位的 因为dll是32位的
选择x86 或者 win32 一般默认都是 x86
然后我们接着点击生成解决方案
关于报错 error MSB8070: 找不到 MSVC 工具集版本“14.42.34433”
我们右键点击ATL01解决方案
属性 -->配置属性–>高级
选择一个自己拥有的msvc版本(每个人的都不同)
点击确定以后 我们再来进行生成解决方案
我们看到输出框
ok 接着添加ATL简单对象
右键ATL01–>添加–>新建项–>ATL
取名 ATLtest
这个ProgID 是我们自己填写的 也是我们需要记得的
如 ATLtest01
点击完成
2.4、编写ATL代码
我们需要打开这几个文件
在ATLtest.h 添加一个函数 STDMETHODIMP Test();
并将其实现定义
引入我们的第三方库 如 lib 、dll 、.h
看我的dll是32位的
去 ATL01.idl 文件 interface IATLtest : IDispatch 中添加 [id(1)] HRESULT Test();
好了一切准备就绪 点击编译/生成解决方案
没关系我们进行手动注册
2.5、注册,注册表
xx.exe /RegServer
找到我们的exe位置 由于是debug的 所以在debug文件夹中
2.6、测试程序
我们现在赶快编写一个测试程序试试吧
我们创建了一个命令行项目
#include "Windows.h"
#include "ATL01_i.h"
#include "ATL01_i.c"int main()
{IUnknown* pICRead;CLSID clsid;HRESULT hr;IATLtest* read;
/*
这个类型就是我们在ATL01.idl文件中
interface IATLtest : IDispatch
{[id(1)] HRESULT Test();
};
*/ hr = CoInitialize(NULL);hr = ::CLSIDFromProgID(L"ATLtest01", &clsid); //这个ATLtest01就是我们之前需要记住的 ProgIDhr = CoCreateInstance(clsid, NULL, CLSCTX_LOCAL_SERVER, IID_IUnknown, (void**)&pICRead);pICRead->QueryInterface(IID_IATLtest, (void**)&read); // IID_IATLtest 只是我们的类型前面添加 IID_read->Test(); //这个就是我们编写的调用函数pICRead->Release();read->Release();CoUninitialize();}
欧克 已经具备了 我们启动一下
2.7、可能出现的错误
我们发现失败了 报错了
我们来到 ATLtest.rgs 文件
CLSID
ProgID
::CLSIDFromString 参数填写CLSID
::CLSIDFromProgID 参数填写ProgID
我们发现windowns返回
REGDB_E_CLASSNOTREG Class not registered
证明是我们注册时出现了问题
我们将用到的dll放在同一目录下
我们进行注册
再次进行测试
我们发现就成功了