[C++ / VS2005] runtime DLL laden

Pagina: 1
Acties:

Acties:
  • 0 Henk 'm!

  • liquid_ice
  • Registratie: Februari 2001
  • Laatst online: 08-09 14:43
Ik ben bezig met wat oefen programma's met DLL's en lib's.

Nu heb ik voorbeeld code van:
http://msdn.microsoft.com/en-us/library/ms682507(VS.85).aspx
en
http://msdn.microsoft.com/en-us/library/ms686944(VS.85).aspx

Ik snap wat dat er moet gebeuren, maar het werkt bij mij niet.
De functie GetProcAddress returned een NULL en als ik dan GetLastError doe krijg is 127 (ERROR_PROC_NOT_FOUND).

Mijn DLL heeft in de solution een eigen vcproj die ook een DLL (DLLSensor.dll) oplevert als ik deze bouw.
Mijn code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
// The myPuts function writes a null-terminated string to
// the standard output device.
 
// The export mechanism used here is the __declspec(export)
// method supported by Microsoft Visual Studio, but any
// other export method supported by your development
// environment may be substituted.
 
 
#include <windows.h>
 
#define EOF (-1)
 
#ifdef __cplusplus    // If used by C++ code, 
extern "C" {          // we need to export the C interface
#endif
 
__declspec(dllexport) int __cdecl myPuts(LPWSTR lpszMsg)
{
    DWORD cchWritten;
    HANDLE hConout;
    BOOL fRet;
 
    // Get a handle to the console output device.

    hConout = CreateFileW(L"CONOUT$",
                         GENERIC_WRITE,
                         FILE_SHARE_WRITE,
                         NULL,
                         OPEN_EXISTING,
                         FILE_ATTRIBUTE_NORMAL,
                         NULL);

    if (INVALID_HANDLE_VALUE == hConout)
        return EOF;
 
    // Write a null-terminated string to the console output device.
 
    while (*lpszMsg != L'\0')
    {
        fRet = WriteConsole(hConout, lpszMsg, 1, &cchWritten, NULL);
        if( (FALSE == fRet) || (1 != cchWritten) )
            return EOF;
        lpszMsg++;
    }
    return 1;
}
 
#ifdef __cplusplus
}
#endif


In de cpp van mijn class DLLSensorFinder staat nu deze code:
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
#include "DLLSensorFinder.h"
#include <windows.h> 
#include <stdio.h> 
 
typedef int (__cdecl *MYPROC)(LPWSTR); 

DLLSensorFinder::DLLSensorFinder()
{
  HINSTANCE hinstLib; 
  MYPROC ProcAdd; 
  BOOL fFreeResult, fRunTimeLinkSuccess = FALSE; 

  hinstLib = LoadLibrary(TEXT("DLLSensor")); 
  if (hinstLib != NULL) 
  {         
    ProcAdd = (MYPROC) GetProcAddress(hinstLib, "myPuts"); 
 
    // If the function address is valid, call the function.
 
    if (NULL != ProcAdd) 
    {
        fRunTimeLinkSuccess = TRUE;
        (ProcAdd) (L"Message sent to the DLL function\n"); 
    }
    else
    {
        DWORD error = GetLastError();
        error = error;
    }
    // Free the DLL module.
    fFreeResult = FreeLibrary(hinstLib); 
  }
  else
  {
    printf("DLL Not found");
  }
}


Wat doe ik nog verkeerd?

Klus page: http://klusthuis.blogspot.com


Acties:
  • 0 Henk 'm!

  • MLM
  • Registratie: Juli 2004
  • Laatst online: 12-03-2023

MLM

aka Zolo

Gebruik the dependency walker (depends.exe) die in de platform SDK zit (of google en download), en check dat je DLL inderdaad dat symbool bevat. Je moet aan GetProcAddress de exacte unmangled naam van het symbool zijn, wil het werken.

Kan je ook checken of je symbool wel echt geexporteerd word

-niks-


Acties:
  • 0 Henk 'm!

  • liquid_ice
  • Registratie: Februari 2001
  • Laatst online: 08-09 14:43
Als ik met dependency walker kijk, dan zie ik dat in mijn DLL de MSVCR80D.DLL en de KERNEL32.DLL zit.
Als ik op een van die 2 DLL's klik, dan krijg ik rechts allemaal dingen te zien (geexporteerde functies denk ik?)
Maar als ik op mijn DLLSENSOR.DLL klik, dat zie ik niks.

De functie is dan dus niet geexporteerd?

Klus page: http://klusthuis.blogspot.com


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 20:04
Klopt, het wil wel eens helpen om een export definition bestand aan te maken ( .def ) zodat de compiler weet welke symbolen moeten worden geexporteerd.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • liquid_ice
  • Registratie: Februari 2001
  • Laatst online: 08-09 14:43
Kan je dan een .def maken als je bijv. van een externe partner een DLL hebt gekregen met een header file erbij?

want een .def file is toch gewoon een andere manier (work around).

[ Voor 23% gewijzigd door liquid_ice op 22-02-2009 19:09 ]

Klus page: http://klusthuis.blogspot.com


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 20:04
Een def file gebruikt de compiler om te bepalen welke symbolen moeten worden geexporteerd, niet hoe je functies moet importeren. Overigens is een def file niet een workaround, het verplaatst het export verhaal alleen naar buiten de code zelf.

Met de header en dll in je bezit kun je wel de functies in de dll dynamisch laden ( met LoadLibrary en GetProcAddress )

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • Soultaker
  • Registratie: September 2000
  • Nu online
Je kunt wel een .def file gebruiken waarschijnlijk, maar dat verklaart nog niet waarom die __declspec(dllexport) niet werkt, wat ik wel had verwacht. Dat lijkt me interessanter om te weten.

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-09 16:37

.oisyn

Moderator Devschuur®

Demotivational Speaker

Weet je zeker dat je wel naar de goede DLL zit te kijken? VC++ linkt standaard naar een Release of Debug directory, wellicht dat je een oude (waar die hele functie niet in stond) ooit eens hebt gekopiëerd naar een andere locatie en die nu steeds laadt middels LoadLibrary()?

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 20:04
Soultaker schreef op zondag 22 februari 2009 @ 23:22:
Je kunt wel een .def file gebruiken waarschijnlijk, maar dat verklaart nog niet waarom die __declspec(dllexport) niet werkt, wat ik wel had verwacht. Dat lijkt me interessanter om te weten.
Kan het zijn dat voor de correcte werking een switch moet worden meegegeven oid?

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-09 16:37

.oisyn

Moderator Devschuur®

Demotivational Speaker

Vziw niet.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Sebazzz
  • Registratie: September 2006
  • Laatst online: 18:21

Sebazzz

3dp

Ik kan vertellen dat ik met het compileren van de SQLite3 dll merkte dat Visual Studio 2008 pas functies liet exporteren met een .def bestand én __declspec(dllexport). Met alleen __declspec(dllexport) deed hij niets exporteren.

offtopic:
@.oisyn: Je website geeft foutmeldingen.

[ Voor 11% gewijzigd door Sebazzz op 23-02-2009 12:39 ]

[Te koop: 3D printers] [Website] Agile tools: [Return: retrospectives] [Pokertime: planning poker]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 22-09 16:37

.oisyn

Moderator Devschuur®

Demotivational Speaker

Liet ie echt daadwerkelijk pas functies exporteren met een .def, of exporteerde hij alleen unmangled functies met een .def. Want dat laatste is dus een issue in C++, als je geen extern "C" gebruikt dan krijg je gewoon de mangled namen.

Of linkte de DLL tegen een lib waar al die functies in stonden? Want dan krijg je de issue dat de contents uit de lib pas geinclude worden als die symbols gereferenced worden in het DLL project. Een .def file zorgt voor dergelijke references.

offtopic:
I know, de server config is veranderd en hier moet ik nog een oplossing voor verzinnen... Wat doe je trouwens op mijn al jaren niet meer geüpdatete website? :P

[ Voor 48% gewijzigd door .oisyn op 23-02-2009 13:03 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • farlane
  • Registratie: Maart 2000
  • Laatst online: 20:04
Sebazzz schreef op maandag 23 februari 2009 @ 12:37:
Ik kan vertellen dat ik met het compileren van de SQLite3 dll merkte dat Visual Studio 2008 pas functies liet exporteren met een .def bestand én __declspec(dllexport).
Kan me herinneren dat ik ook een .def heb gebruikt om diezelfde reden; je hoeft echter niet beide methoden te gebruiken, aleen een .def voldoet ook.

Somniferous whisperings of scarlet fields. Sleep calling me and in my dreams i wander. My reality is abandoned (I traverse afar). Not a care if I never everwake.

Pagina: 1