2013-12-26 4 views
1

Обычно я создал DLL на C++. В этом случае я делаю попытку с использованием D. . Мой прогресс пока заключается в том, что я могу получить такие структуры, как ZooInformation. Но у меня проблема с Zookeeper, которая содержит чистые виртуальные функции. Как перевести это в D и вызывать функции Zookeeper так же, как это делается на C++?C++ DLL в D (Чистые виртуальные функции)

/* 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

Смотрите эту страницу на веб-сайте D, а именно «Вызов C++ Виртуальные функции D» раздел: Interfacing to C++

Сопряжение с чисто виртуальными функциями не должно быть иначе, как с другими виртуальными функциями. Если вы столкнулись с определенной проблемой, предоставьте более подробную информацию.

+0

Я прочитал статью, которую вы связали и используя информацию, указанную в качестве примера, попытки вызвать виртуальные функции C++ приведут к ошибке APPCRASH. У вас есть пример того, как должен быть .d для ZooKeeper? Благодаря! –

+0

Моя неудачная попытка сделать это можно найти по адресу http://codepad.org/OvBCTsnq –

+0

«попытки вызвать виртуальные функции C++ приведут к ошибке APPCRASH» - ну, это ожидается, если вы фактически не передадите экземпляр, который реализует эти виртуальные методы. Кроме того, в коде, который вы опубликовали, отсутствует декларация 'ZooKeeper'. Не могли бы вы обновить свой вопрос и добавить все соответствующие коды? –

Смежные вопросы