Forum: PC-Programmierung C++ Friend-Deklaratio bei Klassen in DLL


von hansi_a (Gast)


Lesenswert?

Hallo,

ich habe eine Klasse in einer DLL
1
class __declspec(DllExport) Ape {
2
public:
3
    friend class V3D;
4
    Ape ();
5
    ~Ape ();
6
private:
7
   int i;
8
};

in der Anwendung lade ich die DLL und habe dort eine Klasse V3D welche 
auf das private Member i zugreifen soll. (Die ja eigentlich Friend sein 
sollte)

Ich bekomme aber immer die Fehlermeldung, dass es private ist.

Funktinieren Friend Deklarationen nicht wenn die Klasse in einer DLL 
ist?

von tictactoe (Gast)


Lesenswert?

hansi_a schrieb:
> Funktinieren Friend Deklarationen nicht wenn die Klasse in einer DLL
> ist?

Nein, kann damit nichts zu tun haben. Zeig mal, wie du denn auf i 
zugreifst.

von Sebastian Hepp (Gast)


Lesenswert?

Das Problem dürfte hier sein, dass sich das Friend Schlüsselwort nur auf 
das aktuelle Projekt (also die DLL) auswirken kann. Sobald die DLL 
kompiliert und gelinkt worden ist, gibt es ja keine Informationen mehr 
für das friend, weil es in der fertigen Datei nur noch Maschinencode und 
keine Klassennamen mehr gibt.

von Rufus Τ. F. (rufus) Benutzerseite


Lesenswert?

Sebastian Hepp schrieb:
> Sobald die DLL kompiliert und gelinkt worden ist, gibt es ja keine
> Informationen mehr für das friend, weil es in der fertigen Datei nur
> noch Maschinencode und keine Klassennamen mehr gibt.

Nö, das ist eine C++-DLL, die nur bei Verwendung der zugehörigen 
Headerdatei (mit Klassendeklaration) verwendbar ist; die exportierten 
Symbole der DLL sind mit "name mangling" versehen, wie sie es auch bei 
einer statisch zu linkenden Library wären.

von Noch einer (Gast)


Lesenswert?

>die exportierten Symbole der DLL

Sind die private member, auf die dein friend zugreifen will, überhaupt 
exportiert?

Mit dumpbin nachschauen.

von Noch einer (Gast)


Lesenswert?

Eigentlich ist "friend" in einer DLL eine recht schräge Idee.

Im realen Leben sagst du ja auch nicht -- jeder der behauptet, er heisst 
"Klaus" ist mein Freund.

von Florian (Gast)


Lesenswert?

Noch einer schrieb:
> Eigentlich ist "friend" in einer DLL eine recht schräge Idee.

Genau. "friend" verwendet man so sparsam wie möglich und nur für 
Klassen, die sehr eng mit anderen Klassen bzw. Funktionen 
zusammenarbeiten (aber eben aus verschiedenen Gründen nicht in der 
Klasse selbst implementiert werden sollen). Dementsprechend gehört der 
ganze Klumpatsch dann normalerweise auch in eine gemeinsame Bibliothek 
und wird nicht willkürlich getrennt.

von Florian (Gast)


Lesenswert?

Florian schrieb:
> "friend" verwendet man so sparsam wie möglich und nur für
> Klassen, die sehr eng mit anderen Klassen bzw. Funktionen
> zusammenarbeiten (aber eben aus verschiedenen Gründen nicht in der
> Klasse selbst implementiert werden sollen).

Etwas wirr.
... (aber die entsprechende Funktionalität eben aus verschiedenen 
Gründen - generelles Design, Operandenreihenfolge, ... - nicht in der 
Klasse selbst implementiert werden soll oder kann, aber der Zugriff so 
effizient wie unter den gegebenen Umständen möglich sein soll). Auch 
wenn du einfach nur V3D Zugriff auf i gewähren und ansonsten nicht 
zulassen willst, gehören Ape und V3D sehr wahrscheinlich in die gleiche 
Bibliothek. Oder dein Vorgehen ist insgesamt nicht passend, aber dazu 
müsste man mehr wissen.

BTW: Rein technisch funktioniert es natürlich trotzdem.

ape.h; APEDLL_EXPORTS im DLL-Projekt definieren.
1
#pragma once
2
3
#ifdef APEDLL_EXPORTS
4
#define APEDLL_API __declspec(dllexport) 
5
#else
6
#define APEDLL_API __declspec(dllimport) 
7
#endif
8
9
class APEDLL_API Ape
10
{
11
public:
12
  friend class V3D;
13
private:
14
  int i;
15
};

client.cpp
1
#include "ape.h"
2
3
class V3D
4
{
5
public:
6
  void bla(Ape& ape)
7
  {
8
    ape.i = 99;
9
  }
10
};
11
12
int main()
13
{
14
  V3D v3d;
15
  Ape ape;
16
  v3d.bla(ape);
17
18
  return 0;
19
}

Klappt problemlos.

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.