应用com组件实现32位程序调用64位dll和64位程序调用32dll文件。
以32位调用64位dll为例:
创建64位dll文件
https://www.cnblogs.com/xbit/p/9625743.html
完成后得到*.dll文件,*.lib文件,*.h文件,作为准备文件。
应用ATL创建com组件
点击完成dll的准备文件添加到atl工程中,创建一个ATL简单对象:
添加接口方法:
STDMETHODIMP CCalc::ComSum(LONG a, LONG b, LONG* c)
{
// TODO: 在此添加实现代码
//dll_class dll_obj;
*c = dll_sum(a, b);
return S_OK;
}
重载函数
HRESULT PreMessageLoop(int nShowCmd)
{
// TODO: 在此添加专用代码和/或调用基类
HRESULT hr = ::CoInitializeSecurity(NULL, -1, NULL, NULL, RPC_C_AUTHN_LEVEL_NONE, RPC_C_IMP_LEVEL_IDENTIFY, NULL, EOAC_NONE, NULL);
if (FAILED(hr))
{
ATLASSERT(FALSE);
return hr;
}
hr = this->RegisterClassObjects(CLSCTX_LOCAL_SERVER, REGCLS_SINGLEUSE);
if (hr == S_OK) { if (m_bDelayShutdown && !this->StartMonitor()) { hr = E_FAIL; } }
else { m_bDelayShutdown = false; }
ATLASSERT(SUCCEEDED(hr));
return hr;
}
//重载该函数,在执行完常规注册以后将接口软件的自定义属性写入注册表
bool ParseCommandLine(LPCTSTR lpCmdLine, HRESULT* pnRetCode) throw()
{
*pnRetCode = S_OK;
TCHAR szTokens[] = _T("-/");
LPCTSTR lpszToken = FindOneOf(lpCmdLine, szTokens);
while (lpszToken != NULL)
{
if (WordCmpI(lpszToken, _T("UnregServer")) == 0)
{
*pnRetCode = this->UnregisterServer(TRUE);
*pnRetCode = this->UnregisterAppId();
return false;
}
// Register as Local Server
if (WordCmpI(lpszToken, _T("RegServer")) == 0)
{
*pnRetCode = this->RegisterAppId();
if (SUCCEEDED(*pnRetCode)) *pnRetCode = this->RegisterServer(TRUE);
//向注册表写入自定义属性注册信息并注册实施类别
if (SUCCEEDED(*pnRetCode)) {}
return false;
}
lpszToken = FindOneOf(lpszToken, szTokens);
}
return true;
}
修改工程.rgs
NoRemove AppID
{
'%APPID%' = s 'Test64Dll'
'Test64Dll.EXE'
{
val AppID = s '%APPID%'
}
}
启动COM组件服务程序:
以管理员身份运行,在DCOM组件服务中查看启动该程序。WIN+R中输入dcomcnfg。
创建32位的应用程序,
将ATL文件中的Test64Dll_i.c,Test64Dll_i.h文件拷贝到项目文件
Test64Dll_i.c文件去掉预编译头选项
进行编译,可以实现32位程序调用64dll。