D中的C ++ DLL(纯虚函数)

时间:2013-12-26 01:05:00

标签: d

通常,我用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());
}

1 个答案:

答案 0 :(得分:0)

在D网站上查看此页面,特别是“从D调用C ++虚拟函数”部分:Interfacing to C++

与纯虚函数的接口应该与其他虚函数没有区别。如果您遇到特定问题,请提供更多详细信息。