You are not logged in.

  • Login

1

Friday, October 20th 2006, 6:45pm

DLL einbinden

Hallo zusammen


ich habe folgendes Problem beim einbinden einer DLL. Wenn ich die DLL direkt in der Hauptfunktion _tmain() einbinde, dann funktioniert das wunderbar. Sobald ich aber eine eigene Klasse erstelle, ist es nicht möglich in dieser Klasse die DLL einzubinden. Die DLL verwendet den Namespace "MyDll".

Das Beispiel von main.cpp funktioniert wunderbar:

main.cpp

C Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#define LOAD_FUNCTION_POINTER
#include "MyDllObjectDefs.h"
 
void *notifyFunc( MyDll::NotificationType notificationType,
                  void *data)
{
   return NULL;
}
 
int clientId;
 
int _tmain(int argc, _TCHAR* argv[])
{
   bool res;
 
   res = MyDll::loadMyDll("MyDll.dll");
 
   if (res) {
      clientId = MyDll::startMyDllClient("192.168.1.20", 8080, notifyFunc, MyDll::ProtocolType_MyDll);
   }
 
   return 0;
}


Das nun folgende leider nicht...

main1.cpp

C Quellcode

1
2
3
4
5
6
7
8
#include "MyObject.cpp"
 
int _tmain(int argc, _TCHAR* argv[])
{
   myObject *my = new MyObject();
 
   return 0;
}


myObject.h

C Quellcode

1
2
3
4
5
6
7
8
9
10
#pragma once
 
class myObject
{
public:
	myObject(void);
	~myObject(void);
protected:
	int m_clientId;
};


myObject.cpp

C Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
#include myObject.h
 
#define LOAD_FUNCTION_POINTER
#include "MyDllObjectDefs.h"
 
void *notifyFunc( MyDll::NotificationType notificationType,
                  void *data)
{
   return NULL;
}
 
myObject::myObject(void)
: m_clientId(0)
{
   res = MyDll::loadMyDll("MyDll.dll");
 
   if (res) {
      m_clientId = MyDll::startMyDllClient("192.168.1.20", 8080, notifyFunc, MyDll::ProtocolType_MyDll);
   }
}
 
myObject::~myObject(void)
{
}


Ich hoffe die Codeausschnitte reichen für eine Beurteilung. Besten Dank für eure Hinweise.

triple-m

2

Monday, October 23rd 2006, 12:05pm

Was kommt denn für eine Fehlermeldung?
Fehlt da evtl. irgendwo ein "__declspec(dllimport)"?

3

Monday, October 23rd 2006, 4:46pm

hallo phax

es scheint jetzt mal soweit zu funktionieren. es liegt an dem

C Quellcode

1
#define LOAD_FUNCTION_POINTER

Ich habe es aus main1.cpp entfernt und verwende es nur noch in MyObject.cpp. Dafür kann ich jetzt in main1.cpp auch keine Funktionen der DLL aufrufen. Naja das ist ja nicht weiter schlimm, dann ist wenigstens die DLL schon mal sauber gekapselt.

hier noch ein kleiner Auszug aus der MyDllInterface.h:
Mit LOAD_FUNCTION_POINTER scheint er die Funktionen aus der DLL dem Programm verfügbar zu machen.

C Quellcode

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
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
/*-----------------------------------------------------------------------------------
              define  CREATE_FUNCTION_POINTER to get all function pointer
  -----------------------------------------------------------------------------------*/
  #ifdef LOAD_FUNCTION_POINTER
  #define CREATE_FUNCTION_POINTER
  #endif
 
  #ifdef CREATE_FUNCTION_POINTER 
  #undef CREATE_FUNCTION_POINTER
 
    #ifdef WIN32
    typedef void              (*SetLogFile)           (const MyDllChar *);
    typedef void              (*SetLogfileSize)       (MyDllUInt);
    typedef void              (*SetLogLevel)          (const MyDllChar *,
                                                       LogLevel);
    #endif  //    #ifdef WIN32
 
    typedef MyDllBool        (*StopMyDllServer)     (MyDllPort); 
    typedef sendResults       (*SendServer)           (MyDllMsg &);
    typedef sendResults       (*SendClient)           (MyDllMsg &);
    typedef void              (*AcceptClientSessions) (MyDllBool); 
    typedef MyDllClientId    (*StartMyDllClient)    (const MyDllChar *,
                                                       const MyDllInt,
                                                       NotifyFunc &,
                                                       const ProtocolType protocolType); 
    typedef MyDllBool        (*StopMyDllClient)     (MyDllClientId); 
    typedef MyDllBool        (*StartMyDllServer)    (const MyDllPort,
                                                       NotifyFunc &,
                                                       const ProtocolType protocolType); 
    typedef void              (*StopMyDll)           (void) ;
 
    #ifdef WIN32
    SetLogFile                fpSetLogFile            = 0;
    SetLogfileSize            fpSetLogfileSize        = 0;
    SetLogLevel               fpSetLogLevel           = 0;
    #endif  //     #ifdef WIN32
 
    StartMyDllServer         fpStartMyDllServer     = 0;
    StopMyDllServer          fpStopMyDllServer      = 0;
    AcceptClientSessions      fpAcceptClientSessions  = 0;
    StartMyDllClient         fpStartMyDllClient     = 0;
    StopMyDllClient          fpStopMyDllClient      = 0;
    SendServer                fpSendServer            = 0;
    SendClient                fpSendClient            = 0;
    StopMyDll                fpStopMyDll            = 0;
  #endif   //#ifdef CREATE_FUNCTION_POINTER 
 
  /*-----------------------------------------------------------------------------------
          define  LOAD_FUNCTION_POINTER to get the function pointer loader function
  -----------------------------------------------------------------------------------*/
  #ifdef LOAD_FUNCTION_POINTER
  #undef LOAD_FUNCTION_POINTER
    static HINSTANCE hMyLib = 0 ;
    static char *loadDllError = 0;
 
    bool loadMyDll(const char *libName)
    {
      hMyLib = LoadLibrary(libName);
      if (!hMyLib) 
      {
        #ifdef __linux__
          loadDllError = dlerror();
					printf("dlerror=%s\n",loadDllError);
        #endif  //  #ifdef __linux__
 
        return false ;
      }
 
      // Get function pointers
      fpStartMyDllServer = (StartMyDllServer) GetProcAddress(hMyLib, "startMyDllServer"); 
      if (!fpStartMyDllServer) return false;
 
      fpStopMyDllServer = (StopMyDllServer) GetProcAddress(hMyLib, "stopMyDllServer"); 
      if (!fpStopMyDllServer) return false ;
 
      fpAcceptClientSessions = (AcceptClientSessions) GetProcAddress(hMyLib, "acceptClientSessions"); 
      if (!fpAcceptClientSessions) return false ;
 
      fpStartMyDllClient = (StartMyDllClient) GetProcAddress(hMyLib, "startMyDllClient"); 
      if (!fpStartMyDllClient) return false;
 
      fpStopMyDllClient = (StopMyDllClient) GetProcAddress(hMyLib, "stopMyDllClient"); 
      if (!fpStopMyDllClient) return false;
 
      fpSendServer = (SendServer) GetProcAddress(hMyLib, "sendServer"); 
      if (!fpSendServer) return false ;
 
      fpSendClient = (SendClient) GetProcAddress(hMyLib, "sendClient"); 
      if (!fpSendClient) return false ;
 
      fpStopMyDll = (StopMyDll) GetProcAddress(hMyLib, "stopMyDll"); 
      if (!fpStopMyDll) return false;
 
      #ifdef WIN32
 
      fpSetLogFile = (SetLogFile) GetProcAddress(hMyLib, "setLogFile"); 
      if (!fpSetLogFile) return false;
 
      fpSetLogfileSize = (SetLogfileSize) GetProcAddress(hMyLib, "setLogfileSize"); 
      if (!fpSetLogfileSize) return false;
 
      fpSetLogLevel = (SetLogLevel) GetProcAddress(hMyLib, "setLogLevel"); 
      if (!fpSetLogLevel) return false;
 
      #endif //  #ifdef WIN32
      return true ;
    }
 
    #define sendServer(a)               (MyDll::fpSendServer)            (a)
    #define sendClient(a)               (MyDll::fpSendClient)            (a)
    #define stopMyDllClient(a)         (MyDll::fpStopMyDllClient)      (a)
    #define startMyDllClient(a,b,c,d)  (MyDll::fpStartMyDllClient)     (a,b,c,d)
    #define acceptClientSessions(a)     (MyDll::fpAcceptClientSessions)  (a)
    #define startMyDllServer(a,b,c)    (MyDll::fpStartMyDllServer)     (a,b,c)
    #define stopMyDllServer(a)         (MyDll::fpStopMyDllServer)      (a)
    #define stopMyDll()                (MyDll::fpStopMyDll)            () 
 
    #ifdef WIN32
    #define setLogFile(a)               (MyDll::fpSetLogFile)            (a)
    #define setLogfileSize(a)           (MyDll::fpSetLogfileSize)        (a)
    #define setLogLevel(a,b)            (MyDll::fpSetLogLevel)           (a,b)
    #endif  //     #ifdef WIN32
  #endif //   #ifdef LOAD_FUNCTION_POINTER


Jetzt steht aber das nächste Problem an. Der dritte Parameter von startMyDllClient ist ein Callback. Im Beispiel verwende ich dort eine Funktion (void * notifyFunc), die global definiert ist. Das funktioniert auch, aber wenn diese Funktion aufgerufen wird, dann habe ich kein Bezug zum Objekt. Also deklariere ich die Callback Funktion als Klassenmember. Doch als Callback kann ich nur eine statische Memberfunktion angeben und da bin ich wieder gleich weit. Unter http://www.newty.de/fpt/callback.html habe ich gelesen, dass ich eine Wrapper Funktion schreiben muss, doch irgendwie komm ich damit auch nicht weiter. Example A geht nicht, da ich die Funktionsparameter der Callback Funktion nicht verändern kann (die DLL ist nich von mir). Und Example B funktioniert zwar mit einer Instanz von myObject, aber was wenn ich mehr Instanzen erstellen will? Wie gehe ich am besten vor?

Besten Dank, triple-m

4

Thursday, October 26th 2006, 4:52pm

hab die Lösung gefunden! im zweiten Parameter ist irgendwo auch die IP des Servers drin versteckt. Diese kann ich verwenden um zu unterscheiden wer das Callback auslöste.

bye triple-m

Similar threads

Social bookmarks