[疑难] 如何通过模板自动生成c++可以用的VTable

heroboy 2007-09-28
因为D的interface和c++的抽象类不兼容,所以要手动做一个VTable,有什么办法吗?
class A
{
	bool foo(int,char){return true;}
	int bar(){return 1;}
	void Release(){delete this;}
}
template VTable(alias T,p ...)
{
	struct VTable
	{
		auto x0 = &v0;//error?
	}
	static ReturnType!(p[0]) v0(T* t,ParameterTypeTuple!(p[0]))
	{
		return t.p[0](...);//这里应该怎么调用?
	};
}
void main()
{
	alias VTable!(A,A.foo,A.bar,A.Release) Avt;
}
oldrev 2007-09-28
D并不完完全支持C++的ABI,手动作 vtable 可以使用 struct,不过 C++ 类的调用约定必须为 C 或 PASCAL。

如果要与COM交互,用 extern(Windows) interface IXxxx;
heroboy 2007-09-28
我知道D和c++ abi不兼容。
我只是想用d写一个dll让c++调用。如果用c的方式的话,需要导出很多函数,对于GetProcAddress方式的话,很麻烦;用lib文件和。h文件的话,更麻烦。所以一般只导出一个函数,来创建一个对象,让c++调用它的虚函数。这样也比较好控制一个对象的生命周期。
比如对于上面的class A;我希望能通过模板生成:
struct AVTable
{
    void * foo;
    void * bar;
    void * release;
    AVTable opCall()
    {
        foo = cast(void*)extern(C) function int(void* o,int,char)
        {
             AObject * oo = cast(AObject*)o;
             oo.This.foo(...);
        }
    }
}
AVTable avtable = AVTable();
struct AObject
{
    void * vptr;
    A * This;
}
extern(C) export void CreateA(A** ppa)
{
    *ppa = new AObject;
    (*ppa).vptr=casr(void*)&avtable;
    (*ppa).This = new A;
}

我希望上面的东西能自动生成,越自动越好。以此来看看d到底有多强啊,是不是我想得到的,都做得到。
tomqyp 2007-09-28
做这个不如先试试找一些,VC和BCB之间共用DLL导出类的办法,能搞定这个我想你的问题肯定可以解决。
oldrev 2007-09-28
heroboy 写道
我知道D和c++ abi不兼容。
我只是想用d写一个dll让c++调用。如果用c的方式的话,需要导出很多函数,对于GetProcAddress方式的话,很麻烦;用lib文件和。h文件的话,更麻烦。所以一般只导出一个函数,来创建一个对象,让c++调用它的虚函数。这样也比较好控制一个对象的生命周期。
比如对于上面的class A;我希望能通过模板生成:
struct AVTable
{
    void * foo;
    void * bar;
    void * release;
    AVTable opCall()
    {
        foo = cast(void*)extern(C) function int(void* o,int,char)
        {
             AObject * oo = cast(AObject*)o;
             oo.This.foo(...);
        }
    }
}
AVTable avtable = AVTable();
struct AObject
{
    void * vptr;
    A * This;
}
extern(C) export void CreateA(A** ppa)
{
    *ppa = new AObject;
    (*ppa).vptr=casr(void*)&avtable;
    (*ppa).This = new A;
}

我希望上面的东西能自动生成,越自动越好。以此来看看d到底有多强啊,是不是我想得到的,都做得到。

如此的话你仍然需要在 .h 中声明类,就跟纯 C 使用 COM 差不多
oldrev 2007-09-28
访问类的 vtbl 可以直接用 A.classinfo.vtbl,很遗憾 D 编译时只有读文件的能力,如果有写文件的能力的话可以直接生成 C++ 的头文件

heroboy 2007-09-28
不需要啊
c++里:
class IA
{
    virtual int foo(int,char)=0;
};
IA * pA = NULL;
CreateA(&pA);
pA->foo(..);

不过c++的this指针是通过什么传的?ecx?eax?
还有,ls的vtable不对的
对于d里面的class A需要生成一个代理对象,这个代理对象是一个struct,包含一个新的vptr和指向A的指针。
struct AObject
{
void * vptr;
A * t;
}
vptr中的函数:
int foo(..)
{
//这时候this是AObject
//如何得到c++传过来的this
this.t.foo(...);
}
tomqyp 2007-09-28
VC编译的目标代码是通过ecx来存放this指针的,怎么传this这个好像没有明确规定,各种编译器结果可能不同.
heroboy 2007-09-29
我看了一下c++,如果使用stdcall的话,this就是第一个参数。
否则的话,com是如何跨语言的呢
tomqyp 2007-10-01
又仔细读了一遍楼主的贴子,同时也补了补C++对象模型的课,感觉这个办法却实很巧妙,不过相对如何自动生成,有几个问题似乎更应该优先考虑,比如不同的C++编译器产生的对象的二进制结构略有不同,即使是Vptr所在对象的位置也会不同,怎样降低这方面的偶合性.另外楼主的方案只提供了一个创建对象的方法,是不是还应该做一些保证对象不被GC还有销毁对象的工作。不知道楼主现在走到了哪一步,观注中
Global site tag (gtag.js) - Google Analytics