通常,我用C ++创建了DLL。对于这种情况,我正在尝试使用D. 到目前为止,我的进展是能够获得ZooInformation等结构。 但是,我遇到了包含纯虚函数的Zookeeper问题。 如何将其转换为D并且能够像在C ++中一样调用Zookeeper的函数?
/* Zoo.h interface file */
struct ZooInformation
{
char organization[128];
int year;
};
struct Animal
{
char name[128];
int age;
};
struct ZooKeeper
{
virtual int __stdcall GetID();
virtual int __stdcall GetAge();
virtual time_t __stdcall GetDOB();
virtual void __stdcall GetAnimal(Animal *a);
virtual int _stdcall AddAnimal(const Animal *a);
};
/* hooks*/
void APIENTRY InitializeZoo(ZooInformation *zi);
int APIENTRY StartZoo(ZooKeeper *zk);
void APIENTRY ZooStarted();
/* C++ way of implementing Zoo.h */
/* you don't call the hooks directly */
/* the hooks are triggered and you do your logic accordingly */
; ZooDLL.def
LIBRARY ZooDLL
EXPORTS
InitializeZoo
StartZoo
ZooStarted
/* ZooDLL.cpp */
#include "Zoo.h"
ZooKeeper *zk_ = NULL;
BOOL APIENTRY DllMain(HANDLE hModule, DWORD ul_reason_for_call, LPVOID lpReserved)
{
switch(ul_reason_for_call)
{
case DLL_PROCESS_ATTACH:
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
void InitializeZoo(ZooInformation *zi)
{
/* i have to fill ZooInformation myself */
if(zi != NULL)
{
ZooInformation zi_ = { "StackOverflow Zoo", 2013 };
memcpy(zi, &zi_, sizeof(ZooInformation));
}
}
int APIENTRY StartZoo(ZooKeeper *zk)
{
/* we do not need to initialize ZooKeeper ourself */
/* it is returned by StartZoo */
if(zk != NULL)
{
zk_ = zk;
return TRUE;
}
return FALSE;
}
void APIENTRY ZooStarted()
{
cout << "ID: " << zk_.GetID() << endl;
cout << "Age: " << zk_.GetAge() << endl;
}
/* D way of implementing Zoo.h */
/* template code generated by D when creating a DLL project */
/* dllmain.d */
; dll.def
; linker definition file
;
; when creating DLLs a definition file should always be specified because of
; http://d.puremagic.com/issues/show_bug.cgi?id=8130
EXETYPE NT
LIBRARY "DynamicLib.dll"
CODE PRELOAD DISCARDABLE
DATA PRELOAD MULTIPLE
; there's also bug http://d.puremagic.com/issues/show_bug.cgi?id=3956 causing
; inconsistent naming for symbols with "export" specifier
; The workaround is to list the names in the EXPORT section translating the name to itself:
; EXPORTS
; Symbol Symbol
EXPORTS
InitializeZoo
StartZoo
ZooStarted
module dllmain;
import std.c.windows.windows;
import core.sys.windows.dll;
import std.stdio;
extern (C++)
struct ZooInformation
{
char[128] organization;
int year;
}
extern (C++)
interface ZooKeeper
{
extern (Windows) int GetID();
extern (Windows) int GetAge();
}
_gshared HINSTANCE g_hInst;
_gshared ZooKeeper zk_;
extern (Windows)
BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved)
{
final switch (ulReason)
{
case DLL_PROCESS_ATTACH:
g_hInst = hInstance;
dll_process_attach( hInstance, true );
break;
case DLL_PROCESS_DETACH:
dll_process_detach( hInstance, true );
break;
case DLL_THREAD_ATTACH:
dll_thread_attach( true, true );
break;
case DLL_THREAD_DETACH:
dll_thread_detach( true, true );
break;
}
return true;
}
extern (Windows)
void InitializeZoo(ZooInformation *zi)
{
zi.year = 2013;
}
extern (Windows)
int StartZoo(ZooKeeper zk)
{
if(zk != null)
{
zk_ = zk;
return 1;
}
return 0;
}
extern (Windows)
void ZooStarted()
{
writeln("ID: " + zk_.GetID());
writeln("Age: " + zk_.GetAge());
}
答案 0 :(得分:0)
在D网站上查看此页面,特别是“从D调用C ++虚拟函数”部分:Interfacing to C++
与纯虚函数的接口应该与其他虚函数没有区别。如果您遇到特定问题,请提供更多详细信息。