**一个简单的模拟程序出了点问题,大虾进来看看***
我通过注册表来加载我的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