C++中的对象是不能直接在Delphi中用的,主要是在Delphi中没有C++的类声明,不知道传递过来的内存块的结构。
即便是把C++的类翻译到Delphi中,也是不能直接使用的,因为两种语言对对象的结构组织是不同的。
但两者有一点相同,就是虚拟方法表,只要我们保证两边声明的类的虚拟方法表一致,就可以实现在Delphi中调用C++对象的虚方法。
举例:
C++中有个类如下
class CTest {
public:
virtual void* __cdecl OpenDocument(wchar_t* a);
};
注意,由于是利用虚拟方法表的机制,所以方法必须声明为虚方法,另外,C++的类方法调用约定是__thiscall,这在Delphi中是没有的,所以要改为__cdcel(__stdcall也可以,只要两边一致就行)
然后我们需要导出一个函数生成CTest对象
extern "C" __declspec(dllexport) CTest* CreateTest(void);
OK,C++这边的工作完成了。
Delphi这边首先要导入该函数
function CreateTest(): TTest; cdecl; external 'Test.dll';
TTest = class(TObject)
public
function OpenDocument(AFilename: PWideChar): Pointer; virtual; cdecl; abstract;
end;
由于真正的对象是在C++中创建,Delphi这边只需要把虚拟方法表对应上就行,故此处把方法都声明为抽象方法,不需要实现,而这个类也不会在Delphi中去创建。
做完这些后,就可以把C++中的对象传递给Delphi了,Delphi里也可以像普通对象一样去调用它的方法(当然是声明的这些虚方法)。
需要注意的是,类在两边声明时的虚拟方法必须顺序一样,简单类这还是好保证的,但如果有类继承这就不是那么好保证了。熟悉Delphi的同学知道,Delphi中所有的类都是从一个基类TObject派生下来的,而TObject本身就有8个虚方法。从上例中,我们可以大胆猜测,Delphi中是子类的虚拟方法在表的前面,父类的虚拟方法在后面。这样刚好和C++对应上。