我写个dll,封装了ado的部分功能,这个类里面有 纪录集指针, 做为私有成员, 
函数代码如下: _RecordsetPtr   CSqlOperateDll::Query(TCHAR* sql)
{
_variant_t ra; if(sql==NULL)
{
throw _T("sql语句为空");
} if(m_pConn==NULL)
{
throw _T("数据库没有打开");
} //查询 try
{
m_pRes.CreateInstance(_uuidof(Recordset));
m_pRes->Open(_bstr_t(sql),m_pConn.GetInterfacePtr(), adOpenDynamic, adLockOptimistic, adCmdText);
}  catch(_com_error e)///捕捉异常 
     {  
CString errormessage; 
errormessage.Format(_T("修改记录失败!\r\n错误信息:%s") ,e.ErrorMessage() ); 
AfxMessageBox(errormessage);

     } 
 return  m_pRes;    //返回记录集,供其他程序用
}
代码应该没有问题啊 ,对吧?为了测试这个函数的正确性,我写了基于对话框的程序来测试, 结果立即报错。error LNK2019: 无法解析的外部符号 "public: class _com_ptr_t<class _com_IIID<struct ADODB::_Recordset,&struct __s_GUID const _GUID_00000556_0000_0010_8000_00aa006d2ea4> > __thiscall CSqlOperateDll::Query(char *)" (?Query@CSqlOperateDll@@QAE?AV?$_com_ptr_t@V?$_com_IIID@U_Recordset@ADODB@@$1?_GUID_00000556_0000_0010_8000_00aa006d2ea4@@3U__s_GUID@@B@@@@PAD@Z),该符号在函数 "public: void __thiscall CTestDlg::OnBnClickedButton1(void)" (?OnBnClickedButton1@CTestDlg@@QAEXXZ) 中被引用
意思是找不到这个函数,无法解析,lib, .h文件都拷到了测试程序的目录下面, 也#pragma comment(lib,..)了所以不存在没有拷lib文件的说法了。而把这个dll的.h    .cpp文件放在对话框的工程之下,直接包含,不用dll,就没有错误。很奇怪,
这是为什么啊? 

解决方案 »

  1.   

     __declspec(dllexport) _RecordsetPtr CSqlOperateDll::Query(TCHAR* sql);
    CSqlOperateDll类需要导出
      

  2.   

    class _declspec(dllexport) CSqlOperateDll
    {
    public:
    CSqlOperateDll(void);
    ~CSqlOperateDll(void);public:
      BOOL  ConnDataBase();            // 初始化com,并连接数据库,用户名字,密码等信息已经在函数体里面
      BOOL DisConn();                           //断开连接,并做善后工作public:      
     _RecordsetPtr   Query(TCHAR* sql);                //查询
     BOOL ExecSql(TCHAR* sql);             //执行sql,不返回记集  private:
     _ConnectionPtr m_pConn;              //连接指针
       _RecordsetPtr   m_pRes;               //结果集指针
         
    };
      

  3.   

     void CTestDlg::OnBnClickedButton1()
    {   /*
    try
    {
    sql.Query(_T("nihao"));    //报错 }
    catch(char* error)
    {
    AfxMessageBox(error);
    }
    */ if(sql.ConnDataBase())   //为什么这个可以调用, 不会报错呢? {
    AfxMessageBox(_T("dddddd"));
    }
    }
      

  4.   

    别返回_RecordsetPtr了。
    写几个类似movefirst,movenext,getstring什么的封装函数吧
      

  5.   

    #pragma warning( disable : 4146 )#import "C:\program files\common files\System\ado\msado15.dll" no_namespace \
    rename("EOF","EndOfFile") \
    rename("LockTypeEnum","newLockTypeEnum")\
    rename("DataTypeEnum","newDataTypeEnum")\
    rename("FieldAttributeEnum","newFieldAttributeEnum")\
    rename("EditModeEnum","newEditModeEnum")\
    rename("RecordStatusEnum","newRecordStatusEnum")\
    rename("ParameterDirectionEnum","newParameterDirectionEnum")在stdafx.h里加这个试一下