[疑难] 如何通过模板自动生成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还有销毁对象的工作。不知道楼主现在走到了哪一步,观注中
|