[疑难] xpcom.dll为何不能正常加载?

qiezi 2007-04-12
要解决这个问题也是可以的,不直接调用接口的QueryInterface,而是调用一个通用的QueryInterfaceX,在它里面调用接口的QueryInterface,完成之后把虚表指针减少一个指针大小就可以了。
就是有点麻烦。

GUID是难看点,不过以后IPv6了,IP地址也一样难看。资源多了嘛就得用这么长的东西来管理。
oldrev 2007-04-12
还有个 std.windows.unknown.d
qiezi 2007-04-12
oldrev 写道
还有个 std.windows.unknown.d

没看到哪里用这个,而且它是个class,不知道做什么的。
oldrev 2007-04-12
在D里用COM好像很麻烦,唯一只有 juno 项目提供了一个 tlbimpd 的程序为导入库生成D声明,偶尔还会产生错误。
tlbimpd 产生的类还依赖 juno.com,虽然可以手工修改,可是毕竟很麻烦,尤其是像 mshtml.tlb 这样3万多行的文件
qiezi 2007-04-12
不是D里面用COM麻烦,是导入库太少。。可以自己只写一些自己要用到的,还是比较方便的,比起其它语言来说。
h_rain 2007-04-12
class NS_NO_VTABLE nsISupports {
public:
  NS_IMETHOD QueryInterface(REFNSIID aIID, void** aInstancePtr) = 0;
  NS_IMETHOD_(nsrefcnt) AddRef(void) = 0;
  NS_IMETHOD_(nsrefcnt) Release(void) = 0;
};

#define NS_DEFINE_STATIC_IID_ACCESSOR(the_iid) \
  static const nsIID& GetIID() {static const nsIID iid = the_iid; return iid;}


class NS_NO_VTABLE nsIComponentManager : public nsISupports {
 public: 

  NS_DEFINE_STATIC_IID_ACCESSOR(NS_ICOMPONENTMANAGER_IID)

  NS_IMETHOD GetClassObject(const nsCID & aClass, const nsIID & aIID, void * *result) = 0;

  NS_IMETHOD GetClassObjectByContractID(const char *aContractID, const nsIID & aIID, void * *result) = 0;

  NS_IMETHOD CreateInstance(const nsCID & aClass, nsISupports *aDelegate, const nsIID & aIID, void * *result) = 0;

  NS_IMETHOD CreateInstanceByContractID(const char *aContractID, nsISupports *aDelegate, const nsIID & aIID, void * *result) = 0;

};



nsIComponentManager* cm;
nsresult rv;
rv = NS_GetComponentManager(&cm);



这东西乱呼呼的一片!
我在Mozilla中找到的代码片段
qiezi 2007-04-12
nsIComponentManager里的方法我还没用到,没有影响,它排在虚表后面。现在的问题是COM对象虚表第1个元素不知道是什么,第2个才是COM对象的第1个方法QueryInterface,extern(Windows)声明的接口和它是对应的,而XPCOM对象虚表第1个就是QueryInterface方法,extern(Windows)把它跳过了。想到了解决办法,就是不美观,晚点测试一下。
oldrev 2007-04-12
搞不懂了,既然叫“跨平台COM” 怎么还用 Windows 的调用约定,按道理应该是 extern(C) 啊
qiezi 2007-04-12
是调用约定。extern(C)是cdecl,extern(Windows)其实是__stdcall,不是说Windows专有的。

区别是extern(C)声明的函数由调用者清理堆栈,extern(Windows)由函数自己清理堆栈。另外接口中的方法也是extern(Windows)的,this作为参数压入堆栈,否则this指针是从寄存器传入。
h_rain 2007-04-12
typedef struct IM0
{
	int QueryInterface;
	int AddRef;
	int Release;
	int GetClassObject;
	int GetClassObjectByContractID;
	int CreateInstance;
	int CreateInstanceByContractID;
}IM0;

typedef struct IM1
{
	struct IM0 *p;
}IM1;

    nsIComponentManager* cm;
	nsresult rv;
	rv = NS_GetComponentManager(&cm);

	printf("0x%08x=QueryInterface\r\n",cm->QueryInterface);
	printf("0x%08x=AddRef\r\n",cm->AddRef);
	printf("0x%08x=Release\r\n",cm->Release);
	printf("0x%08x=GetClassObject\r\n",cm->GetClassObject);
	printf("0x%08x=GetClassObjectByContractID\r\n",cm->GetClassObjectByContractID);
	printf("0x%08x=CreateInstance\r\n",cm->CreateInstance);
	printf("0x%08x=CreateInstanceByContractID\r\n\r\n",cm->CreateInstanceByContractID);

	IM1 *m=(IM1*)cm;
	printf("0x%08x=QueryInterface\r\n",m->p->QueryInterface);
	printf("0x%08x=AddRef\r\n",m->p->AddRef);
	printf("0x%08x=Release\r\n",m->p->Release);
	printf("0x%08x=GetClassObject\r\n",m->p->GetClassObject);
	printf("0x%08x=GetClassObjectByContractID\r\n",m->p->GetClassObjectByContractID);
	printf("0x%08x=CreateInstance\r\n",m->p->CreateInstance);
	printf("0x%08x=CreateInstanceByContractID\r\n\r\n",m->p->CreateInstanceByContractID);


	rv = NS_GetComponentManager((nsIComponentManager**)&m);
	printf("0x%08x=QueryInterface\r\n",m->p->QueryInterface);
	printf("0x%08x=AddRef\r\n",m->p->AddRef);
	printf("0x%08x=Release\r\n",m->p->Release);
	printf("0x%08x=GetClassObject\r\n",m->p->GetClassObject);
	printf("0x%08x=GetClassObjectByContractID\r\n",m->p->GetClassObjectByContractID);
	printf("0x%08x=CreateInstance\r\n",m->p->CreateInstance);
	printf("0x%08x=CreateInstanceByContractID\r\n\r\n",m->p->CreateInstanceByContractID);


输出
0x0042ecde=QueryInterface
0x0042ee4b=AddRef
0x0042f00d=Release
0x0042ecb1=GetClassObject
0x0042dd16=GetClassObjectByContractID
0x0042de33=CreateInstance
0x0042ddf7=CreateInstanceByContractID

0x10065b50=QueryInterface
0x10065a00=AddRef
0x10065a70=Release
0x10067bf0=GetClassObject
0x10067d30=GetClassObjectByContractID
0x10068250=CreateInstance
0x10068380=CreateInstanceByContractID

0x10065b50=QueryInterface
0x10065a00=AddRef
0x10065a70=Release
0x10067bf0=GetClassObject
0x10067d30=GetClassObjectByContractID
0x10068250=CreateInstance
0x10068380=CreateInstanceByContractID


为什么cm->QueryInterface与m->p->QueryInterface的值不一样?
是不是因为这是成员函数指针啊?直接这么显示与调用的时候的真实取址不一样?
Global site tag (gtag.js) - Google Analytics