首页 诗词 字典 板报 句子 名言 友答 励志 学校 网站地图
当前位置: 首页 > 教程频道 > 开发语言 > VC/MFC >

*一个简单的模拟程序出了点有关问题,进来看看*

2012-01-23 
**一个简单的模拟程序出了点问题,大虾进来看看***我通过注册表来加载我的DLL(实际上我是在模拟COM),然后在

**一个简单的模拟程序出了点问题,大虾进来看看***
我通过注册表来加载我的DLL(实际上我是在模拟COM),然后在客户程序通过COM库的
CoGetClassObject得到我的接口指针的指针,这样就能访问我的组件了。可是我在客户测试程序里调试到CoGetClassObject这个函数调用的地方时总是弹出 "unhandle   exception   in   InterfaceTest.exe:   0xC0000005:Access   Violation "这样的错误提示对话框,而且还有更奇怪的问题,下面我先将代码贴出来(否则难说明问题),然后再讲出现的问题,望各位路过的高人能耐心的帮看下。

//   下面是接口类的头文件
//   dllsrv.h


#ifndef   _DLLSRV_INCLUDE_
#define   _DLLSRV_INCLUDE_

#include   <objbase.h>
#include   <ole2.h>

class   IMyClass
{
public:
virtual   void   _stdcall   fun1()=0;
virtual   void   _stdcall   fun2()=0;
};

//   GUID   :

//   {53160E37-4EB9-4205-83FE-1EBFE1D68671}
static   const   GUID   CLSID_DLLSRVMYCLASS   =  
{   0x53160e37,   0x4eb9,   0x4205,   {   0x83,   0xfe,   0x1e,   0xbf,   0xe1,   0xd6,   0x86,   0x71   }   };

//   {416A2E43-9BFC-4ac1-B652-5479175963D0}
static   const   GUID   IID_IDDLLSRVMYINTERFACE   =  
{   0x416a2e43,   0x9bfc,   0x4ac1,   {   0xb6,   0x52,   0x54,   0x79,   0x17,   0x59,   0x63,   0xd0   }   };

#endif   //   _DLLSRV_INCLUDE_

/////////////////////////////////////////////////////


//   下面是组件类的头文件
//   dllsrvimp.h

#ifndef   _DLLSRVIMP_INCLUDE_
#define   _DLLSRVIMP_INCLUDE_

#include   "dllsrv.h "

class   CMyClass:public   IMyClass
{
public:
//     constructor
        CMyClass();
public:
//implement   interface   functions
virtual   void   _stdcall   fun1();
virtual   void   _stdcall   fun2();

};

#endif   //   _DLLSRVIMP_INCLUDE_

/////////////////////////////////
//   下面是组件类的实现文件
//  

#include   <iostream>
#include   "dllsrvimp.h "
using   namespace   std;

CMyClass::CMyClass()
{
   
}

void   _stdcall   CMyClass::fun1()
{
cout < < "the   fun1()   is   in   my   dll " < <endl;

}

void   _stdcall   CMyClass::fun2()
{
cout < < "the   fun2()   is   in   my   dll " < <endl;
}

CMyClass   g_Obj;


/**********************************

    DllGetClassObject函数被导出
    最终被COM库自动调用,用来产
    生一个对象的指针的地址

************************************/
STDAPI   DllGetClassObject(REFCLSID   rclsid,REFIID   riid,void   **ppv)
{
if(rclsid!=CLSID_DLLSRVMYCLASS){//   Is   this   the   number   of   our   class?
       
return   CLASS_E_CLASSNOTAVAILABLE;
      }
if(riid!=IID_IDDLLSRVMYINTERFACE){   //   Is   this   the   number   of   our   interface?  

return   E_INVALIDARG;
    }

        *ppv   =   (IMyClass*)&g_Obj;
      return   NO_ERROR;
}

好了上面就是整个DLL的内容,简单吧^_^
下面看客户的测试程序(只是个简单的控制台程序,为了方便测试):


#include   <windows.h>


#include   <winerror.h>
#include   "dllsrv.h "   //包含了接口类的声明
#include   <iostream>
#include   <comdef.h>
#include   <stdio.h>
using   namespace   std;

int   main()
{
      CoInitialize(NULL);          
      IMyClass   *pObj=NULL;
      HRESULT   hRes;
      try{

      hRes   =   CoGetClassObject(CLSID_DLLSRVMYCLASS,CLSCTX_SERVER,NULL,
  ===> (1):           IID_IDDLLSRVMYINTERFACE,(void**)&pObj);
      }
      catch(_com_error   &e)
      {
          cout < <e.ErrorMessage() < <endl;
  return   0;
      }
      if(FAILED(hRes))
      {
      char   buf[100]= " ";
      sprintf(buf, "Error   %x   create   MyClass   Object! ");
      cout < <buf < <endl;
      return   0;
      }
     
      pObj-> fun1();
      pObj-> fun2();
     
      CoUninitialize();
return   0;
}
说明一下:我已经手工的在注册表的HKEY_CLASSES_ROOT\CLSID下建立好了子键
名称是:{53160E37-4EB9-4205-83FE-1EBFE1D68671}就是组件的GUID嘛,
然后在这个GUID下再建立一个名为InprocServer32的子键,里面放DLL路径


我调试到(1)这个地方就出现上面说的错误了。还有,如果我不进行F5调试而直接运行客户的测试程序,控制抬屏幕输出 "the   fun2()   is   in   my   dll "然后就弹出经常见的
”XXX.exe出现问题,需要关闭“这样提示的对话框,又如果我不调用
      pObj-> fun1();
      pObj-> fun2();
这两句,直接运行客户测试程序,屏幕同样有 "the   fun2()   is   in   my   dll "字样输出,后同样出现错误关闭对话框。是不是我COM规范中那些没实现好呢?我知道我的模拟程序并不是实际上的COM程序,但从上面可以看出DLL应该是被COM库加载了,请大哥们指点指点.

[解决办法]
接口定义错误!组件至少应该从IUnknown派生,实现那3个函数
class IMyClass

热点排行