Herzlich Willkommen, lieber Gast!
  Sie befinden sich hier:

  Forum » VC++ / MFC » DLL korrekt ?

Forum | Hilfe | Team | Links | Impressum | > Suche < | Mitglieder | Registrieren | Einloggen
  Quicklinks: MSDN-Online || STL || clib Reference Grundlagen || Literatur || E-Books || Zubehör || > F.A.Q. < || Downloads   

Autor Thread - Seiten: > 1 <
000
04.08.2006, 07:07 Uhr
muck2000



Moin,

arbeite mich gerade in die DLL Nutzung ein, und möchte mal wissen ob das was ich da produziert habe auch korrekt ist.

Ich hab ne "Standart DLL, MFC-DLL verwenden" erstellt. (mit VC++ 6.0)

Zum probieren, wollte ich meine Funktion zum erstellen des eines Tray-Icons in die DLL schreiben, da man das ja öfter brauchen kann.

Meine DLL

C++:
// NormDLL.cpp : Legt die Initialisierungsroutinen für die DLL fest.
//

#include "stdafx.h"
#include "NormDLL.h"

#ifdef _DEBUG
#define new DEBUG_NEW
#undef THIS_FILE
static char THIS_FILE[] = __FILE__;
#endif

//

.
.
.

/////////////////////////////////////////////////////////////////////////////
// CNormDLLApp

BEGIN_MESSAGE_MAP(CNormDLLApp, CWinApp)
    //{{AFX_MSG_MAP(CNormDLLApp)
        // HINWEIS - Hier werden Mapping-Makros vom Klassen-Assistenten eingefügt und entfernt.
        //    Innerhalb dieser generierten Quelltextabschnitte NICHTS VERÄNDERN!
    //}}AFX_MSG_MAP
END_MESSAGE_MAP()

/////////////////////////////////////////////////////////////////////////////
// CNormDLLApp Konstruktion

CNormDLLApp::CNormDLLApp()
{
    // ZU ERLEDIGEN: Hier Code zur Konstruktion einfügen
    // Alle wichtigen Initialisierungen in InitInstance platzieren
}

/////////////////////////////////////////////////////////////////////////////
// Das einzige CNormDLLApp-Objekt

CNormDLLApp theApp;

extern "C" __declspec(dllexport) void TrayIconErstellen(int trayIconID, int userID, int iconID, HWND m_hWnd)
{
    //AFX_MANAGE_STATE(AfxGetStaticModuleState());
    
    NOTIFYICONDATA nid;
    memset(&nid, 0, sizeof(NOTIFYICONDATA));

    nid.cbSize = sizeof(NOTIFYICONDATA);
    nid.hIcon = AfxGetApp()->LoadIcon(iconID);
    nid.hWnd = m_hWnd;
    _tcsncpy(nid.szTip, "Test Icon", sizeof(nid.szTip));
    nid.uCallbackMessage = userID;
    nid.uFlags = NIF_ICON | NIF_TIP | NIF_MESSAGE;
    nid.uID = trayIconID;

    Shell_NotifyIcon(NIM_ADD, &nid);
}



In meiner Dialoganwendung steht folgendes:

C++:
.
.
#define TRAY_ICON_ID (WM_USER + 111)
#define WM_USER_TRAY (WM_USER + 100)
.
.
.
extern "C" __declspec(dllimport) void TrayIconErstellen(int trayIconID, int userID, int iconID, HWND m_hWnd);

void CProgDlg::OnTest()
{
    HWND m_hWnd = CWnd::GetSafeHwnd();
    TrayIconErstellen(TRAY_ICON_ID, WM_USER_TRAY, IDR_MAINFRAME, m_hWnd);    
}



Funktioniert "fast" einwandfrei.

3 Fragen:

1. Ist das korrekt so?

2. Wo ruf ich "extern "C" __declspec(dllimport) void ..." korrekterweise auf? Im Moment steht es einfach vor der Funktion in der ich es benötige.

3. In meinem Buch steht:"Wird diese DLL dynamisch an die MFC-DLLs gebunden, muss bei allen von dieser DLL exportierten Funktionen, die MFC-Aufrufe durchführen, das Makro AFX_MANAGE_STATE direkt am Beginn der Funktion eingefügt sein."

Wenn ich diese Makro einfüge, erschein statt des gewälten TrayIcons nur ein graues Viereck in der Tray-Leiste.

Im Voraus vielen Dank.


Gruß Sven
--
Nimm das Leben nicht so ernst, da es eine Sache ist aus der Du eh nicht lebend raus kommst!

Dieser Post wurde am 04.08.2006 um 07:08 Uhr von muck2000 editiert.
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
001
04.08.2006, 09:39 Uhr
xXx
Devil


Mach ne einfache WinAPI Dll... mit ner DllMain usw.. Leg dir nen Macro an, das dir selbständig aussucht ob dllimport oder dllexport richtig ist... fertig
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
002
04.08.2006, 17:49 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


Hi, also

das das so klappt ist zufall bzw "gewollter zufall".

Wenn du AfxManageState aufrufst, wird der Aufruf "AfxGetApp" von deiner Anwendung auf die Instanz der DLL übertragen, darum schlägts beim 2ten mal fehl, da das icon nicht gefunden wird in der dll.

Wenn jetzt aber z.B deine Anwendung KEINE MFC-Anwendung ist, würde dir das Programm um die Ohren fliegen. Darum solltest du lieber die Daten wie z.B das Icon in der DLL speichern wo es auch benutzt wird, oder eben das HICON direkt übergeben, das sollte über DLL-Grenzen hinweg funktionieren. Da du dann natürlich keine MFC mehr in der DLL brauchst, solltest du wie Devil vorgeschlagen, eine normale WinAPI DLL benutzen, muss ja nicht eine DllMain besitzen, kann ja auch rein nur Symbole (in deinem Fall die Funktion) exportieren.

extern "C" bedeutet nur, das funktionsnamenserweiterung nicht stattfindet, also das dann das Symbol in der DLL wirklich so heißt, wie du es im Quellcode spezifizierst.

__declspec(dllexport) weist den VC-Compiler (aber auch nur den) an, das Symbol zu exportieren und nicht wegzuoptimieren.

__declspec(dllimport) dagegen heißt, das er einen stub ("symbolrumpf") in deiner Anwendung erzeugt, welche dann versucht aus einer DLL die Funktion zu importieren. Dafür ist dann auch die lib zuständig, die mit der dll generiert wird, in der stehen diese "stubs" und ihre zuordnung zum dll-namen.

Ansonsten ist die Zeile

extern "C" __declspec(dllimport) void TrayIconErstellen(int trayIconID, int userID, int iconID, HWND m_hWnd);

ein ganz normaler Funktionsprototyp, d.h du kannst sie dorthin schreiben wo du willst.

Normalerweise liefert man einen header zur DLL mit, die dann z.b so aufgebaut ist:


C++:
#ifdef MYDLL_EXPORTS
#  define MYDLL_API extern "C" __declspec(dllexport)
#else
#  define MYDLL_API extern "C" __declspec(dllimport)
#endif

MYDLL_API int MeineExportierteFunktion(int parameter);



und dann in der DLL z.B


C++:
#include "mydll.h"

MYDLL_API int MeineExportierteFunktion(int parameter)
{
  return parameter*2;
}



und in der Anwendung z.B:


C++:
#include "mydll.h"

int main(void)
{
  printf("10 * 2 = %d\n", MeineExportierteFunktion(10));
}



Da der Visual Studio Assistent automatisch für die DLL ein define "MYDLL_EXPORTS" erzeugt (also "MYDLL" ist der name des projekts) funktioniert das, da dieses define natürlich in der richtigen Anwendung dann nicht vorhanden ist. Wie man sieht, kann man so den Header für beide Projekte benutzen, einmal für die DLL selbst, und natürlich für die Anwendung.
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
003
05.08.2006, 15:18 Uhr
muck2000



Hi,

danke für die Antwort.

Das mit dem HICON direkt übergeben war eigentlich auch mein ursprünglicher Plan, aber ich hab´s irgendwie nicht hinbekommen.

Wenn ich das Icon in der DLL speichere müsste ich ja für jede neue Anwendung auch die DLL neu erstellen oder immer das gleiche Icon verwenden.


Gruß Sven
--
Nimm das Leben nicht so ernst, da es eine Sache ist aus der Du eh nicht lebend raus kommst!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
004
05.08.2006, 18:16 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


naja der wahrscheinlich sinnvollere Weg ist der, die Instanz (HINSTANCE) der Hauptanwendung an die funktion mitzugeben und die ID des Icons, und dann mit LoadIcon(hInstance, MAKEINTRESOURCE(idIcon)) das icon zu laden.
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
005
06.08.2006, 15:30 Uhr
muck2000



kannst du mir einen tipp geben wie ich an meine hInstance komme. bei mir steht entweder nichts drin oder nur nullen
--
Nimm das Leben nicht so ernst, da es eine Sache ist aus der Du eh nicht lebend raus kommst!
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
006
06.08.2006, 16:45 Uhr
FloSoft
Medialer Over-Flow
(Administrator)


AfxGetInstanceHandle
--
class God : public ChuckNorris { };
 
Profil || Private Message || Suche Download || Zitatantwort || Editieren || Löschen || IP
Seiten: > 1 <     [ VC++ / MFC ]  


ThWBoard 2.73 FloSoft-Edition
© by Paul Baecher & Felix Gonschorek (www.thwboard.de)

Anpassungen des Forums
© by Flo-Soft (www.flo-soft.de)

Sie sind Besucher: