OPCWorkshop改BCB遇到F1004内部编译错误

华山沦贱 2018-06-10 09:16:19
下载的一个工控用的OPCServer版OPCWorkshop,用VS2010打开编译都正常(VC6.0不能编译),但生成的dll没法用在BCB下面,查看源码,使用了CString及特殊时间类型,于是把全部源码转移到BCB6.0下修改编译。
第一步把所有的CString改成了string,并将CString函数也全转成了string的函数,剔除了VS版本才有的几个头文件并修改部分函数:
//#include <atlstr.h>
//#include <atlsync.h>
//#include <ATLComTime.h>

再编译发现报如下错误:
[C++ Fatal error] atlcom.h(4144): F1004 Internal compiler error at 0x955a94 with base 0x900000

定位在类定义:template <class T, const IID* piid, const GUID* plibid = &CComModule::m_libid, WORD wMajor......
atlcom.h

/////////////////////////////////////////////////////////////////////////////
// IDispatchImpl

template <class T, const IID* piid, const GUID* plibid = &CComModule::m_libid, WORD wMajor = 1,
WORD wMinor = 0, class tihclass = CComTypeInfoHolder>
class ATL_NO_VTABLE IDispatchImpl : public T
{
public:
typedef tihclass _tihclass;
// IDispatch
STDMETHOD(GetTypeInfoCount)(UINT* pctinfo)
{
*pctinfo = 1;
return S_OK;
}
STDMETHOD(GetTypeInfo)(UINT itinfo, LCID lcid, ITypeInfo** pptinfo)
{
return _tih.GetTypeInfo(itinfo, lcid, pptinfo);
}
STDMETHOD(GetIDsOfNames)(REFIID riid, LPOLESTR* rgszNames, UINT cNames,
LCID lcid, DISPID* rgdispid)
{
return _tih.GetIDsOfNames(riid, rgszNames, cNames, lcid, rgdispid);
}
STDMETHOD(Invoke)(DISPID dispidMember, REFIID riid,
LCID lcid, WORD wFlags, DISPPARAMS* pdispparams, VARIANT* pvarResult,
EXCEPINFO* pexcepinfo, UINT* puArgErr)
{
return _tih.Invoke((IDispatch*)this, dispidMember, riid, lcid,
wFlags, pdispparams, pvarResult, pexcepinfo, puArgErr);
}
protected:
static _tihclass _tih;
static HRESULT GetTI(LCID lcid, ITypeInfo** ppInfo)
{
return _tih.GetTI(lcid, ppInfo);
}
};

template <class T, const IID* piid, const GUID* plibid, WORD wMajor, WORD wMinor, class tihclass>
IDispatchImpl<T, piid, plibid, wMajor, wMinor, tihclass>::_tihclass
IDispatchImpl<T, piid, plibid, wMajor, wMinor, tihclass>::_tih =
{piid, plibid, wMajor, wMinor, NULL, 0, NULL, 0};


通过依次注释定位到是 class AG_IErrorInfoImpl : public IDispatchImpl<IErrorInfo, &IID_IErrorInfo> 触发编译错误

#ifndef ERRORINFOIMPLH
#define ERRORINFOIMPLH

#pragma once
//#include "stdafx.h"
#include <atlbase.h>
extern CComModule _Module;
#include <atlcom.h>

template <class T,const CLSID *pclsid = &CLSID_NULL>
class AG_IErrorInfoImpl : public IDispatchImpl<IErrorInfo, &IID_IErrorInfo>
{
protected:
DWORD m_ErrorDescriptionID;
string m_ErrMsg;
public:

AG_IErrorInfoImpl()
{
m_ErrorDescriptionID = 0;
}

void setErrorString(DWORD id, ...)
{
/*
va_list marker;
va_start(marker, id); //Initialize variable arguments.
string format;
format.LoadString(id);
m_ErrMsg.FormatV(format , marker);
va_end(marker); */
m_ErrorDescriptionID = id;
}

void setErrorString(LPCTSTR str)
{
m_ErrMsg = str;
m_ErrorDescriptionID = 1;
}
public:

STDMETHOD(GetGUID)(GUID *pGUID)
{
if(pGUID == NULL) return E_INVALIDARG;
*pGUID = *pclsid;
return S_OK;
}
STDMETHOD(GetSource)(BSTR *pBstrSource)
{
LPOLESTR ptr = NULL;
if(!FAILED(ProgIDFromCLSID(*pclsid, &ptr)))
{
CComBSTR str = ptr;
CoTaskMemFree(ptr);
*pBstrSource = str.Detach();
}
return S_OK;
}
STDMETHOD(GetDescription)(BSTR *pBstrDescription)
{
if(m_ErrorDescriptionID)
{
// CComBSTR str;
// str.LoadString(m_ErrorDescriptionID);
// *pBstrDescription = str.Detach();
// return S_OK;
//}
CComBSTR str = m_ErrMsg.c_str();
*pBstrDescription = str.Detach();
}
return S_OK;
}
STDMETHOD(GetHelpFile)(BSTR *pBstrHelpFile)
{
return E_NOTIMPL;
}
STDMETHOD(GetHelpContext)(DWORD *pdwHelpContext)
{
return E_NOTIMPL;
}

DWORD showMessageBoxByErrorInfo()
{
return ::MessageBox(NULL, m_ErrMsg, _T("COM error!"), MB_OK | MB_ICONERROR);
}
};

class errorDescription
{
string str;
public:
errorDescription(IUnknown *obj)
{
CComQIPtr<IErrorInfo> inf = obj;
if(inf == NULL) return;
CComBSTR msg;
inf->GetDescription(& msg);
str = W2A(msg);
}

operator LPCTSTR()
{
return str.c_str();
}
};

inline DWORD showMessageBoxByErrorInfo(IUnknown *obj)
{
CComQIPtr<IErrorInfo> inf = obj;
if(inf == NULL) return 0;
CComBSTR msg;
inf->GetDescription(& msg);
return ::MessageBox(NULL, W2A(msg), _T("COM error!"), MB_OK | MB_ICONERROR);
}

#endif


在工控领域编程10多年从未用过模板,临时补了下模板还是不知所以然。希望大神们帮忙看看:

OPCWorkshop2.0的serverdll源码在网盘:
链接: https://pan.baidu.com/s/1vSIR6M-n0-Rl0yrzObji6w 密码: 8668

改装bcb6.0的未完成版:
链接: https://pan.baidu.com/s/1SvekPYYRoX04rL12nWZwxw 密码: 8668
...全文
1102 1 打赏 收藏 转发到动态 举报
写回复
用AI写文章
1 条回复
切换为时间正序
请发表友善的回复…
发表回复
cptang 2018-07-19
  • 打赏
  • 举报
回复
这个源码连接方式是DA还是UA?

703

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder ActiveX/COM/DCOM
社区管理员
  • ActiveX/COM/DCOM社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧