Pomoc s vytvořením mé první dll knihovny (DEV-C++) – C / C++ – Fórum – Programujte.com
 x   TIP: Přetáhni ikonu na hlavní panel pro připnutí webu

Pomoc s vytvořením mé první dll knihovny (DEV-C++) – C / C++ – Fórum – Programujte.comPomoc s vytvořením mé první dll knihovny (DEV-C++) – C / C++ – Fórum – Programujte.com

 

Toto vlákno bylo označeno za vyřešené.
end0
Newbie
9. 2. 2014   #1
-
0
-

Zdravím lidi,

nainstaloval jsem si DEV-C++ a zkouším zde vytvořit moji první dll knihovnu, s jednou easy fcí. kterou bych chtěl pak připojit k jiné aplikaci. Nejde mi to ani trochu. Byl by někdo ochoten sem napsat, vložit kod, a postup kompilace do tvaru knihovny dll (prosím česky :-))

Jako základ této fce. v knihovně by mi stačilo, kdyby mi vypsala string a součet dvou double čísel, které by jí byly předány jako parametr. 

Děkuji moc.

Nahlásit jako SPAM
IP: 89.102.130.–
KIIV
~ Moderátor
+43
God of flame
9. 2. 2014   #2
-
0
-

nema to tam nahodou example s jednou tridou, ktery vyrobi jak program, co to pouziva, tak tu dll?

Nahlásit jako SPAM
IP: 94.113.93.–
Program vždy dělá to co naprogramujete, ne to co chcete...
end0
Newbie
9. 2. 2014   #3
-
0
-

#2 KIIV
Jo, má, Já bych tam potřeboval mít vsunutý ty parametry, abych si s tím mohl "hrát", měnit a tak. Nemohu na to přijít.. :-(

Nahlásit jako SPAM
IP: 89.102.130.–
BDS+3
Věrný člen
10. 2. 2014   #4
-
0
-

Toto je velmi jednoduché řešení aplikace s připojením vlastní knihovny:

Projekt knihovny:

dllmain.h:
 

#ifndef _DLLMAIN_H_
#define _DLLMAIN_H_


extern "C"
{
 void __stdcall SomeFunction(double a, double b, 
                             unsigned sizeOut, char *cOut);
}

#endif


dllmain.cpp 

#include <windows.h>
#include <stdio.h>

#include "dllmain.h"

//-------------------------------------------------------

void __stdcall SomeFunction(double a, double b,
                            unsigned sizeOut, char *cOut)
{
   double c = a + b;
   _snprintf(cOut, sizeOut, "Vysledek: %f", c);
}
//-------------------------------------------------------
 
BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
{
    switch (reason)
    {
      case DLL_PROCESS_ATTACH:
        break;

      case DLL_PROCESS_DETACH:
        break;

      case DLL_THREAD_ATTACH:
        break;

      case DLL_THREAD_DETACH:
        break;
    }
    return TRUE;
}

Aplikace:

main1.cpp

#include <stdio.h>
#include <windows.h>

#define SZ_BUFFER 64

//---------------------------------------------------------------
typedef void __stdcall (*FUNKCE) (double a, double b,
                                  unsigned sizeOut, char *cOut);
HMODULE hDLL = NULL; 
FUNKCE pFunkce = NULL; 
//---------------------------------------------------------------
int main(int argc, char *argv[])
{
 hDLL = LoadLibrary("MYDLL1.dll");    
    
 if(hDLL) 
 { 
  pFunkce = (FUNKCE)GetProcAddress(hDLL,"SomeFunction");
  // u některých kompilátorů, je třeba použít "_SomeFunction" 
  
  if(pFunkce)
  {
   double d1=0.65, d2=0.15;
   char txt[SZ_BUFFER];
   pFunkce(d1, d2, SZ_BUFFER, txt);
   printf("Hodnota 1: %f\nHodnota 2: %f\n\n%s\n\n", d1, d2, txt);
   
   pFunkce = NULL; 
  }
  else
  printf("Funkce \'SomeFunction\' nebyla v knihovne MYDLL1.dll nalezena!\n");
  
  FreeLibrary(hDLL); 
  hDLL = NULL; 
 }
 else printf("Chyba inicializace MYDLL1.dll!\n");
 
 printf("\nUkoncete stiskem klavesy Enter");
 getchar();
     
 return 0;
}
Nahlásit jako SPAM
IP: 85.71.83.–
W11 :)
end0
Newbie
11. 2. 2014   #5
-
0
-

#4 BDS
Děkuji, moc si vážím odpovědi. V tom chaosu jsem zapomněl na podstatnou věc, tu knihovnu chci totiž zkusit propojit s jiným kodem a ten je napsaný v jiném jazyce než C/C++. Vím, že to propojení jde udělat - myslím kompilace do takového tvaru, aby to připojení bylo ok.

Někde by se tam mělo objevit  .... __declspec(dllexport)

Tak jestli ještě mohu požádat o revizi kodu? Děkuji.

Nahlásit jako SPAM
IP: 89.102.130.–
BDS+3
Věrný člen
11. 2. 2014   #6
-
0
-

#5 end
moc nechápu, jak propojit s jiným kódem..

ale když tam chceš mít __declspec, tak předpokládám, že by se to mělo udělat takto:

// u aplikace zaměnit
//typedef void __stdcall (*FUNKCE) (double a, double b,
//                                  unsigned sizeOut, char *cOut)
// za:

 typedef void __declspec() (*FUNKCE) (double a, double b,
                                      unsigned sizeOut, char *cOut);

// u DLL změnit
// void __stdcall SomeFunction(double a, double b, 
//                             unsigned sizeOut, char *cOut);
// za:

 void __declspec(dllexport) SomeFunction(double a, double b,
                                         unsigned sizeOut, char *cOut);
Nahlásit jako SPAM
IP: 85.71.83.–
W11 :)
end0
Newbie
12. 2. 2014   #7
-
0
-

#6 BDS
Tak jsem nepokročil ani o krok, krom toho, že jsem vyčerpal už x kombinací, jak to udělat. Něco jsme i zkompiloval, ale připojitelné to není. Připojit k jiné aplikaci - no prostě tu knihovnu dll vezmu a funkci - třeba SomeFunction z ní budu volat s parametry.

třeba takto - je deklarováno napojení na tu knihovnu:

#import "jmenodll.dll"

   double SomeFunction( double, double, string);  //bude vracet double hodnotu

#import

 a v mé aplikaci zapíši:

double suma=SomeFunction(5.5, 10.5);

Možná to bude hloupý dotaz, no ale zeptám se - k vytvoření knihovny potřebuji kod main1.cpp?

Já jen, že když si dám otevřít nový projekt, tak se otevřou dva souboru dll.h a maindll.h,

které nějak popisují v těch hlavičkách ony klíčové nastavení pro funkční dll. Tam se právě objevuje to __declspec (dllimport) a __declspec (dllexport). Jsem to zkusil, zkompilovaný to je, alespoň překladač nic nehlásí, ale při pokusu o připojení v mé aplikaci jsem dostal info:

2014.02.12 07:41:04.875    Cannot find 'SomeFunction' in 'Projekt3.dll'

2014.02.12 07:41:04.875    unresolved import function call

zdroje - newdll.h

#ifndef _DLL_H_
#define _DLL_H_

#if BUILDING_DLL
# define DLLExport __declspec (dllexport)
#else /* Not BUILDING_DLL */
# define DLLimport __declspec (dllimport)
#endif /* Not BUILDING_DLL */

DLLExport double SomeFunction(double, double );


#endif /* _DLL_H_ */

newdllmain.cpp

#include <windows.h>
#include <stdio.h>

#include "newdll.h"

//-------------------------------------------------------
double SomeFunction(double a, double b)
{
   double c = a + b;
   return(c);
}
//-------------------------------------------------------
 
BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
{
    switch (reason)
    {
      case DLL_PROCESS_ATTACH:
        break;

      case DLL_PROCESS_DETACH:
        break;

      case DLL_THREAD_ATTACH:
        break;

      case DLL_THREAD_DETACH:
        break;
    }
    return TRUE;
}
Nahlásit jako SPAM
IP: 89.102.130.–
BDS+3
Věrný člen
12. 2. 2014   #8
-
0
-

Příklad, který jsem zde uvedl, používám bez problémů v mých programech a takto úspěšně importuji funkce z dll i jiných autorů. Jiné způsoby neznám.

main1.cpp je v mém případě kód konzolové aplikace, která slouží k testu MYDLL1.dll a uvedl jsem ji zde, jako ukázku toho, jak importovat funkci z dll. Z vlastní dll nemá nic společného.

Takže ještě jednou:

1 : založ nový projekt DLL a pojmenuj MYDLL1
2a: soubor cpp pojmenuj dllmain.cpp
2b: soubor h pojmenuj dllmain.h

3a: zkopíruj tento kód: 

#ifndef _DLLMAIN_H_
#define _DLLMAIN_H_

extern "C"
{
 void __declspec(dllexport) SomeFunction(double a, double b, 
                             unsigned sizeOut, char *cOut);
}

#endif

3b: otevři soubor dllmain.h

3c: Ctrl+A

3d: Ctrl+V

4a: zkopíruj tento kód:  

#include <windows.h>
#include <stdio.h>

#include "dllmain.h"

//-------------------------------------------------------

void SomeFunction(double a, double b,
                            unsigned sizeOut, char *cOut)
{
   double c = a + b;
   _snprintf(cOut, sizeOut, "Vysledek: %f", c);
}
//-------------------------------------------------------
 
BOOL APIENTRY DllMain (HINSTANCE hInst, DWORD reason, LPVOID reserved)
{
    switch (reason)
    {
      case DLL_PROCESS_ATTACH:
        break;

      case DLL_PROCESS_DETACH:
        break;

      case DLL_THREAD_ATTACH:
        break;

      case DLL_THREAD_DETACH:
        break;
    }
    return TRUE;
}

4b: otevři soubor dllmain.cpp

4c: Ctrl+A

4d: Ctrl+V

5:  Provedeš kompilaci

6: Dynamicky připojitelná knihovna je hotova

Teď jen pro test té dll a test, jestli umíš dynamicky importovat funkce z knihoven:

1. Založ nová projekt konzolové aplikace

  (nejlépe ve stejné složce jako tu dll - důvodem je to, že pak nebudeš muset nastavovat cestu k dll, nebo kopírovat      aplikaci a dll do stejného umístění)

2a: zkopíruj tento kód:  

#include <stdio.h>
#include <windows.h>

#define SZ_BUFFER 64

//---------------------------------------------------------------
typedef void __declspec() (*FUNKCE) (double a, double b,
                                  unsigned sizeOut, char *cOut);
HMODULE hDLL = NULL; 
FUNKCE pFunkce = NULL; 
//---------------------------------------------------------------
int main(int argc, char *argv[])
{
 hDLL = LoadLibrary("MYDLL1.dll");    
    
 if(hDLL) 
 { 
  pFunkce = (FUNKCE)GetProcAddress(hDLL,"SomeFunction");
  // u některých kompilátorů, je třeba použít "_SomeFunction" 
  
  if(pFunkce)
  {
   double d1=0.65, d2=0.15;
   char txt[SZ_BUFFER];
   pFunkce(d1, d2, SZ_BUFFER, txt);
   printf("Hodnota 1: %f\nHodnota 2: %f\n\n%s\n\n", d1, d2, txt);
   
   pFunkce = NULL; 
  }
  else
  printf("Funkce \'SomeFunction\' nebyla v knihovne MYDLL1.dll nalezena!\n");
  
  FreeLibrary(hDLL); 
  hDLL = NULL; 
 }
 else printf("Chyba inicializace MYDLL1.dll!\n");
 
 printf("\nUkoncete stiskem klavesy Enter");
 getchar();
     
 return 0;
}

2b: otevři soubor main.cpp

2c: Ctrl+A

2d: Ctrl+V

3:  Provedeš kompilaci

4: Testovací aplikace je hotova

5. Po spuštění by měla vypsat následující:

Hodnota 1: 0,650000

Hodnota 2: 0,150000

Vysledek: 0,800000

Ukoncete stiskem klavesy Enter

Pokud toto zvládneš, můžeš importovat funkce ze svých vlastních knihoven, nebo i z jakýchkoliv dll, které si seženeš a budeš k nim mít dokumentaci.

ps, pokud nezvládneš ani tento návod, tak se omlouvám, že nejsem dobrý učitel. A v tom případě, se budeš muset obrátit na někoho jiného, nebo se na knihovny zatím ještě vykašlat. ;)

Nahlásit jako SPAM
IP: 85.71.83.–
W11 :)
end0
Newbie
12. 2. 2014   #9
-
0
-

#8 BDS
:-) Děkuju moc, to je návod pro lamy... takže i pro mě. Vše v pořádku. Dokonce jsem si přetypoval i funkci z void na double s návratem, odzkoušel součet a+b plus návratovou hodnotu, také vše ok.

Teď to půjdu implementovat do jiné aplikace, tak jsem zvědav...

Nahlásit jako SPAM
IP: 89.102.130.–
end0
Newbie
12. 2. 2014   #10
-
0
-

!!! Tímto Vám chci MOC poděkovat !!!

Připojení funguje, paráda. No, já zase vystřízlivým až zkusím něco tvořit smyslplnějšího než součet a+b. Ale každý od něčeho začínal..  Ještě jednou děkuji. Mohu se zeptat - zda se vyznáte ve fcích. Win Api? Nemyslím je znát nazpaměť, ale nějaká orientace, přehled, schopnost dohledat a aplikovat do kodu. Děkuji ještě jednou. Je to skvělý pocit, že to funguje.

Nahlásit jako SPAM
IP: 89.102.130.–
BDS+3
Věrný člen
12. 2. 2014   #11
-
0
-

#10 end
Není zač. Jsem rád, že se to povedlo.

Jestli se vyznám ve...?

No co nevím to se většinou dá najít na netu. A když něco nepochopím, nebo nenajdu tak se zeptám. Ono se dá i hodně věcí udělat sice složitěji než je běžné a až časem přijdu na to, jak si práci ulehčit, nebo jak svůj program vylepšit.

Celkově jsem pořád jen začátečník, navíc většinou využívám vcl (což je asi nejsnadnější, ale asi zároveň i nejrychlejší způsob psaní programů. Jsou tu i nějaké nevýhody, ale pro mě většinou nepodstatné.).

Tak hodně úspěchů přeji! ;)

Nahlásit jako SPAM
IP: 85.71.83.–
W11 :)
end0
Newbie
13. 2. 2014   #12
-
0
-

#11 BDS
Ok. Považuji můj dotaz za zodpovězený, takže bych toto vlákno označil za vyřešené -třeba zítra. Co je to za zkratku VLC - editor nebo ??? Pokud by se Ti chtělo zapracovat na něčem smysluplnějším než byl můj příklad součtu, budu rád když napíšeš na endy5 [ALT+64] na seznam. Víc informací po mailu. Budu potřebovat pomoct - myslím, že nic hardcord kódování. Jsou prostě části, které mi unikají - což jsi jaksi viděl sám. Pro Tebe rutina, já bych nad tím strávil kdo ví kolik času. Samozřejmě neočekávám pomoc zdarma. Jak jsem napsal, na mailu více. A díky!

Nahlásit jako SPAM
IP: 89.102.130.–
BDS+3
Věrný člen
13. 2. 2014   #13
-
0
-

Už začíná být tahle diskuse trochu OT..

Takže VCL (Visual Component Library) jeden s prvních odkazů, nalezených googlem:

http://cs.wikipedia.org/wiki/VCL
http://cs.wikipedia.org/wiki/C%2B%2BBuilder

Já používám verzi C++Builderu zvanou "Turbo C++ Explorer 2006", což byla verze s určitými omezeními, ale za to byla zdarma i pro komerční použití. Současný vlastník C++ Builderu nenabízí, alternativu Turba Explorer, ale už jen placené (a dle mého názoru překombinované) produkty (i když bych sem tam potřeboval i unicode komponenty).
V dnešní době existuje v podobné licenci C++ Visual Studio Express (tady, pokud chceš WinForms tak brát pouze verzi 2008, nic novějšího), ale při požití WinForms se spíše doporučuje jazyk C#.

Takže dnes bych šel spíše do "Code::Blocks + wxWidgets" nebo wxDev-C++.

Co se týká pomoci, tak pro Tebe bude určitě lepší, když se budeš ptát na diskuzi, než se učit někdy i nesprávné návyky od trošku pokročilejšího začátečníka, který často navíc nemá ani dostatek volného času. Email a jiné komunikátory používám zřídka ;) Ale když budu mít čas, a budu vědět, tak na diskuzi rád odpovím.

Nahlásit jako SPAM
IP: 85.71.83.–
W11 :)
end0
Newbie
22. 4. 2014   #14
-
0
-

Vracím se do tohoto vlákna a volně bych navázal s následujícím dotazem:

Známý mi napsal kod v C++ - knihovnu. Bohužel se mi nedaří tuto knihovnu připojit k mé aplikaci. Aplikace nemůže najít požadovanou fci. z knihovny. :-(

V knihovně je definována třída, která má fci. s parametrem string a vrací také hodnotu string. Otázka je, jak má být provedena deklarace uvnitř knihovny, aby ta fce (metoda) byla deklarována pro export. A jestli to vůbec lze...? 

Nahlásit jako SPAM
IP: 89.177.14.–
Radek Chalupa
~ Redaktor
+1
Super člen
22. 4. 2014   #15
-
0
-

#14 end
Otázka je co myslíš tím "knihovna"? To je dost široký pojem, může to být jeden (nebo více) hlavičkový soubor obsahující kompletní kód (jako např. ATL) nebo hlavička s deklaracemi a kód je v .cpp, nebo máš hlavičkový soubor a k tomu statickou knihovnu s "kódem" v .lib, popř. DLL...

První případ je nejjednodušší, stačí prostý include, pokud máš i .cpp, musíš tento přidat do projektu, aby překladač a linker měl k disposici kód funkcí, podobně .lib soubor musíš přidat do projektu...

Radek Chalupa 
- individuální konzultace, školení programování (C/C++, WinAPI, COM, ActiveX, ATL, C#, NET Framework, MFC) 
- vývoj software na zakázku 
http://www.radekchalupa.cz

Nahlásit jako SPAM
IP: 89.177.51.–
BDS+3
Věrný člen
22. 4. 2014   #16
-
0
-

#14 end

zatím jen k části

má fci. s parametrem string a vrací také hodnotu string.

ze zkušenosti to nepovažuji za dobrý nápad, v exportované funkci bych nevracel nic jiného než int nebo možná i nějakou pevnou strukturu. Ale možná, když se to správně provede.. no uvidíme co na to odborníci :)

Nahlásit jako SPAM
IP: 85.71.83.–
W11 :)
end0
Newbie
23. 4. 2014   #17
-
0
-

#15 Radek Chalupa
Jde o DLL a export fce ven. A pokud jde o připojení k mé aplikaci - ta není napsaná v C/C++.

S postupem, tak jak jej zde ve vláknu popsal BDS (ještě jednou díky!) mi testovací knihovna DLL chodí ok a komunikace mezi aplikací a knihovnou je v pořádku. Jsem myslel, jestli nemáte někdo třeba nějaký easy funkční kod, knihovnu s nějakou třídou a s vlastní vnitřní metodou, do které bych z venku poslal něco (ideálně string) a ona by vracela změněný string (třeba VELKÁ PÍSMENA).  Abych vyzkoušel jestli to bude komunikovat s mojí aplikací. Se nemohu pohnout z místa.. :-(

Nahlásit jako SPAM
IP: 89.177.14.–
z
~ Anonymní uživatel
268 příspěvků
23. 4. 2014   #18
-
0
-

Nejjednodušší bude napsat zapouzdřující funkce, které schovají ty objekty tak, abys zvenku nemusel řešit jejich vnitřnosti (tj. strukturu C++ objektu toho kterého překladače).

////////////////////
// deklarace

extern "C" {

DLLEXP void * trida_new();
DLLEXP void trida_delete(void * inst);
DLLEXP int trida_metoda(void * inst);

}

////////////////////
// definice

void * trida_new()
{
	trida * obj = new trida();
	return (void *) obj;
}

void trida_delete(void * inst)
{
	obj = (trida *) inst;
	delete obj;
}

int trida_metoda(void * inst)
{
	obj = (trida *) inst;
	return obj->metoda();
}

////////////////////
// pouziti

void * obj = trida_new();
trida_metoda(obj);
trida_delete(obj);
obj = 0;
Nahlásit jako SPAM
IP: 88.101.8.–
z
~ Anonymní uživatel
268 příspěvků
23. 4. 2014   #19
-
0
-

Mám tam chyby, ale na to přijdeš :-)

Nahlásit jako SPAM
IP: 88.101.8.–
Nikol
~ Anonymní uživatel
4 příspěvky
20. 10. 2016   #20
-
-1
-
Mimo téma
BDS -

#1 end
Zdravím lidi :),

chci se zeptat jestli je tu někdo kdo by mi mohl pomoct. Zatím se s Dev ++ seznamuji ve škole, a mám třeba úlohu kterou nevím jak řešit nebo postupovat.

Úloha zní :

Máme schované účtenky z několika nákupů. Jednotlivé položky se objevují na vstupu ve formě dvojic { cena, počet kusů }. Posloupnost je ukončena nulou.

  Sestavte algoritmus pro výpočet celkové utracené částky.

Vím že to bude něco strašně jednoduchého, ale úplně nevím jak vůbec začít  a tak tak jestli by někdo napsal jak by postupoval on nebo pomohl, bla bych moc vděčná.

Nahlásit jako SPAM
IP: 147.32.229.–
BDS+3
Věrný člen
20. 10. 2016   #21
-
0
-

#20 Nikol
a jaký byl důvod umístit otázku do tématu týkajícího Dynamic-link library?

a mimochodem, měla bys nějak začít, ukázat kód a ten teprve řešit.

Nahlásit jako SPAM
IP: 185.69.69.–
W11 :)
21. 10. 2016   #22
-
0
-

#21 BDS
asi neumí založit vlákno ....

hu

Nahlásit jako SPAM
IP: 195.178.67.–
21. 10. 2016   #23
-
0
-

K úloze s účtenkama: připravíš si proměnnou inicializovanou na hodnotu 0, nazveme ji suma. V cyklu budeš potřebovat další dvě proměnné pro cenu a kusy. V každém "oběhu" cyklu si od uživatele vyžádáš cenu a množství. Zadanou cenu vynásobíš zadaným množstvím a tento součin přičteš do suma. Pokud uživatel zadá nulu, opustíš cyklus a vypíšeš obsah suma.

hu

Nahlásit jako SPAM
IP: 195.178.67.–
Zjistit počet nových příspěvků

Přidej příspěvek

Toto téma je starší jak čtvrt roku – přidej svůj příspěvek jen tehdy, máš-li k tématu opravdu co říct!

Ano, opravdu chci reagovat → zobrazí formulář pro přidání příspěvku

×Vložení zdrojáku

×Vložení obrázku

Vložit URL obrázku Vybrat obrázek na disku
Vlož URL adresu obrázku:
Klikni a vyber obrázek z počítače:

×Vložení videa

Aktuálně jsou podporována videa ze serverů YouTube, Vimeo a Dailymotion.
×
 
Podporujeme Gravatara.
Zadej URL adresu Avatara (40 x 40 px) nebo emailovou adresu pro použití Gravatara.
Email nikam neukládáme, po získání Gravatara je zahozen.
-
Pravidla pro psaní příspěvků, používej diakritiku. ENTER pro nový odstavec, SHIFT + ENTER pro nový řádek.
Sledovat nové příspěvky (pouze pro přihlášené)
Sleduj vlákno a v případě přidání nového příspěvku o tom budeš vědět mezi prvními.
Reaguješ na příspěvek:

Uživatelé prohlížející si toto vlákno

Uživatelé on-line: 0 registrovaných, 142 hostů

Podobná vlákna

Dll knihovny — založil Jirka

Konfigurace DLL knihovny — založil VladislavK

Tvroba dll knihovny — založil Tomáš Bosek

Dll knihovny v MASM — založil ONDRA

Moderátoři diskuze

 

Hostujeme u Českého hostingu       ISSN 1801-1586       ⇡ Nahoru Webtea.cz logo © 20032024 Programujte.com
Zasadilo a pěstuje Webtea.cz, šéfredaktor Lukáš Churý