SORU
11 ŞUBAT 2009, ÇARŞAMBA


Dllexport ile bir DLL dışa aktarma fonksiyonları

C windows bir DLL işlevini verme basit bir örnek istiyorum.

Başlığı görmek istiyorum, cpp dosyası ve def eğer kesinlikle gerekliyse () dosya.

Verilen isim olmak istiyorumundecorated. Çoğu standart çağırma (__stdcall?) kullanmak istiyorum. Kullanmak istiyorum__declspec(dllexport)ve DEF dosyası kullanmak zorunda değil.

Örneğin:

  //header
  extern "C"
  {
   __declspec(dllexport) int __stdcall foo(long bar);
  }

  //cpp
  int __stdcall foo(long bar)
  {
    return 0;
  }

Linker eklendi altçizgiler ve/veya sayı (bayt sayar?) kaçmaya çalışıyorum adı.

C # destekleyen ve dllexport aynı Başlığı kullanarak değil, benim için sorun yok. C-stil genel işlevler sadece ihracat C sınıfı yöntemler hakkında herhangi bir bilgi istemiyorum.

GÜNCELLEME

Çağırma dahil değil (iç ve dış kullanarak "C") gibi bana verme isimler, ama bu ne anlama geliyor? verir Pınvoke ne alıyorum ne olursa olsun (.NET), ilan (vb6) ve GetProcAddress beklenebilir? (Arayan oluşturulan gösterici bağlı olacaktır GetProcAddress için sanırım).

Bu DLL gerçekten süslü bir sürü ihtiyacım yok bu yüzden bir başlık dosyası olmadan kullanılmasını istiyorum #başlık bir arayan tarafından kullanılabilir hale getirmek için tanımlar.

Cevap DEF dosyası kullanın ben olmaktan mutluyum.

CEVAP
11 ŞUBAT 2009, ÇARŞAMBA


Eğer düz C ihracatı istiyorsanız, C proje C kullanın . C DLL adı-bozma tüm C izm için (Ad vb.) kullanır. C/C - ^ altında proje ayarları içine giderek C olarak kodunuzu derleyin . İleri, "" hangi cooresponds derleyici /TP /TC geçer. Derleme Gibi bir seçenek yoktur

İhracat/İthalat DLL VC Libs

Gerçekten ne yapmak istediğinizi DLL proje kaynak dosyaları dahil edilecek bir başlık koşullu bir makro tanımlayın:

#ifdef LIBRARY_EXPORTS
#    define LIBRARY_API __declspec(dllexport)
#else
#    define LIBRARY_API __declspec(dllimport)
#endif

İhraç etmek istediğiniz fonksiyonu LIBRARY_API kullandıktan sonra:

LIBRARY_API int GetCoolInteger();

Kütüphane inşa projesi fonksiyonları DLL dosyası için verilmesine neden olacak bu LIBRARY_EXPORTS yapı tanımlamak oluşturun.

LIBRARY_EXPORTS proje tüketen proje Başlığı kitaplık dosyası içeren DLL, tanımlı değil beri tüm fonksiyonları yerine alınır.

Eğer kütüphane çapraz platform olarak ise Windows olmayan bir şey olarak LİBRARY_APİ tanımlayabilirsiniz:

#ifdef _WIN32
#    ifdef LIBRARY_EXPORTS
#        define LIBRARY_API __declspec(dllexport)
#    else
#        define LIBRARY_API __declspec(dllimport)
#    endif
#elseif
#    define LIBRARY_API
#endif

Kullanarak dllexport/DEF dosyaları kullanmak gerekmez C # zaman, eğer DEF dosyaları kullanırsanız dllexport/C # kullanmak zorunda değilsiniz. İki yöntem de aynı görevi farklı şekillerde, bu dllexport/C # Önerilen yöntem olduğuna inanıyorum.

İhracat LoadLibrary/Pınvoke için C DLL işlevleri unmangled

Eğer bu LoadLibrary ve GetProcAddress kullanmak istiyorsanız, ya da belki de yapmaktan Pınvoke .NET dllexport extern "C" satır içi kullanabilirsiniz. Ve yerine GetProcAddress C # kullanıyoruz beri yukarıdan ifdef dans, basit bir dllexport yap gerek yok:

Kod:

#define EXTERN_DLL_EXPORT extern "C" __declspec(dllexport)

EXTERN_DLL_EXPORT int getEngineVersion() {
  return 1;
}

EXTERN_DLL_EXPORT void registerPlugin(Kernel &K) {
  K.getGraphicsServer().addGraphicsDriver(
    auto_ptr<GraphicsServer::GraphicsDriver>(new OpenGLGraphicsDriver())
  );
}

Ve burada ihracat Dumpbin /exports ile neye benziyor:

  Dump of file opengl_plugin.dll

  File Type: DLL

  Section contains the following exports for opengl_plugin.dll

    00000000 characteristics
    49866068 time date stamp Sun Feb 01 19:54:32 2009
        0.00 version
           1 ordinal base
           2 number of functions
           2 number of names

    ordinal hint RVA      name

          1    0 0001110E getEngineVersion = @ILT 265(_getEngineVersion)
          2    1 00011028 registerPlugin = @ILT 35(_registerPlugin)

Bu kod gayet iyi çalışıyor:

m_hDLL = ::LoadLibrary(T"opengl_plugin.dll");

m_pfnGetEngineVersion = reinterpret_cast<fnGetEngineVersion *>(
  ::GetProcAddress(m_hDLL, "getEngineVersion")
);
m_pfnRegisterPlugin = reinterpret_cast<fnRegisterPlugin *>(
  ::GetProcAddress(m_hDLL, "registerPlugin")
);

Bunu Paylaş:
  • Google+
  • E-Posta
Etiketler:

YORUMLAR

SPONSOR VİDEO

Rastgele Yazarlar

  • CMTelly

    CMTelly

    2 Mayıs 2007
  • Vladimir Jenko

    Vladimir Jen

    1 Mart 2010
  • Warner Bros. UK

    Warner Bros.

    6 HAZİRAN 2008