|
Začátečník |
Pokročilý |
Profesionál |
|||||
|
|
|
||||||
Programování ve více jazycích Visual Basic .NET a
Visual C++ .NET |
||||||||
|
|
Budete potřebovat
přibližně 2 hodiny |
|
Operační systém
použitý v příspěvku: Windows XP Vývojové nástroje:
Visual Studio .NET |
||||
|
Vážení čtenáři,
hlavním námětem pro dnešek je problematika
„míchání“ programovacích jazyků. V následujících kapitolách se pokusíme
přijít na to, jak může být pro programátora přínosná práce ve dvou (nebo i
více) programovacích jazycích. Dále se budeme soustředit na praktickou
demonstraci filozofie programování ve více jazycích a vytvoříme dynamicky
linkovanou knihovnu (DLL) v prostředí Visual C++ a posléze využijeme
možností vytvořené knihovny ve Visual Basicu. Věřím, že vás námět dnešní
diskuse zaujal, a proto neztrácejme čas a ponořme se hlouběji do problematiky.
Filozofie programování ve
více jazycích
Možná, že s uvedeným termínem „míchání
programovacích jazyků“ (angl. Mixed Language Programming) se střetáváte poprvé,
možná, že jste o něm již „něco“ slyšeli, no stále nevíte, o co ve skutečnosti
jde. Pojďme se tedy podívat, jak se tato myšlenka dostala do světa, ve kterém
vládnou optimalizované algoritmy a počítačové instrukce. Jak jistě víte,
v počítačovém světe existuje poměrně početná množina programovacích
jazyků, od těch nejstarších (ALGOL, COBOL, FORTRAN), přes C a BASIC až po
nejnovější instance, jakými jsou Visual Basic .NET, Visual C# .NET nebo Visual
C++ .NET. Každý programovací jazyk, který se nachází na určitém vývojovém stupni,
byl v počátcích své tvorby koncipován jako pomůcka pro řešení jistých
problémových úkolů. Zjednodušeně se dá říct, že každý programovací jazyk se na
svou podstatu existence (tedy řešení úkolů, pro které byl stvořen) dívá
z vlastního pohledu. Důkazem tohoto tvrzení jsou někdy zcela specifické
postupy, které musí programátor ve dvou jazycích uskutečnit, aby vyřešil
stejnou úlohu (nejjednodušším příkladem může být zapsání cyklu For ve Visual Basicu
a C++). I když je každý programovací jazyk specifický, všechny jazyky disponují
mnoha „standardními“ konstrukcemi (v analogii s předchozím příkladem, oba
jazyky, Visual Basic i Visual C++ obsahují cyklus For). Rozvineme-li myšlenku,
že každý programovací jazyk byl primárně určen na řešení jistého okruhu
problémů, můžeme dojít k poznání, že jeden jazyk může být vhodnější na
řešení jisté skupiny problémů, zatímco jiný jazyk si zase dobře poradí s jinou,
specifickou množinou úkolů. Jestliže popojedeme v našich úvahách ještě o
krok dále, objevíme samotnou myšlenku programování ve více jazycích. Posuďte
sami: Proč používat na vyřešení jistého problému jazyk, ve kterém je toto
řešení když ne nemožné, tak alespoň hodně obtížné? Nebylo by lepší jednoduše
napsat onu kritickou část programu v jiném jazyce, který si s naším problémem
umí lépe poradit?
Použití teorie míchání
programovacích jazyků může přinést mnoho výhod:
|
Úspora času |
Otázka rozřešení
programátorského problému, se kterým nevíme v prostředí jednoho
jazyka „ani hnout“, se v jiném jazyce může stát otázkou několika málo
okamžiků. |
|
Zlepšení výkonu |
Napsání kritických
částí programu v jiném, nižším, programovacím jazyku může způsobit
citelné zlepšení výkonu aplikace. |
|
Zlepšení rychlosti |
S předchozím bodem
se úzce váže i zlepšení rychlosti programu. V případě, že napíšeme
optimalizovaný kód nižší úrovně, a ten pak využijeme ve stávající aplikaci,
zlepšení rychlosti může být signifikantní. |
|
Znovupoužitelnost programového kódu |
Pokud jsme schopni
napsat nízkoúrovňový kód, který později „zabalíme“ do komponenty pro další
použití, nemusíme již tuto část kódu psát opět později. Jednoduše využijeme
to, co již máme připravené. |
Pro úplnost výkladu je zapotřebí vzpomenout i některé
stinné stránky této teorie programování.
|
Vědomostní úroveň |
Jde o úroveň
znalostí a schopností, kterou musí programátor disponovat. Ne každý
programátor totiž umí dobře programovat ve více jazycích. V této
souvislosti není možno zapomenout na prvotní zvýšené náklady na zvýšení
znalostní úrovně programátora. Může jít např. o absolvování specializovaného
programátorského kurzu, nákup literatury a pod. |
|
Nutnost vlastnit další programovací nástroj |
Pokud se
rozhodnete pro programování ve více jazycích, budete pravděpodobně muset
investovat do nákupu dalšího vývojového nástroje, kterého cena může značně
ovlivnit váš rozpočet pro vyvíjenou aplikaci. |
V dnešní případové studii budeme společně
řešit jeden z nejčastějších úkolů programátora pracujícího
v prostředí dvou programovacích jazyků. Půjde o vytvoření dynamicky
linkované knihovny (DLL) ve Visual C++ a následně její implementace do aplikace
vyvíjené ve Visual Basicu.
|
Pokud náhodou patříte mezi skupinu programátorů VB, kterým se při
vyslovení názvů „C/C++“, případně „Visual C++“ udělá špatně, nemusíte se již
více obávat a můžete zůstat zcela klidní. V tomto článku totiž
nepředpokládám, že máte nějaké zkušenosti jak s jazykem C/C++, tak
s vývojovým prostředím Visual C++. V celém článku se uplatňuje
ověřená technika postupu stylem „krok za krokem“, proto se nemusíte obávat
jakýchkoliv nejasností. Uvidíte, že po přečtení následujících řádků budete i
vy schopni vytvořit jednoduchou DLL ve Visual C++. |
Visual Basic .NET a Visual C++ .NET
Krok 1: Tvorba dynamicky linkované knihovny
(DLL) ve Visual C++ .NET
V následující ukázce vytvoříme standardní
dynamicky linkovou knihovnu typu Win32, která bude obsahovat jednu funkci pro
výpočet třetí mocniny čísla. Postupujte takto:
|
Stejného účinku můžete docílit i klepnutím na ikonu New Project na standardním panelu
ikon, nebo klepnutím na tlačítko New
Project v okně Start Page.
Pokud okno Start Page po spuštění Visual Studia není viditelné, klepněte na
nabídku Help a aktivujte položku Show Start Page. |
Obr. 1 – Okno pro výběr nového typu projektu
V levé části okna, v sekci Project
Types, vyberte jako typ projektu Visual C++ Projects. V pravé části okna, v sekci Templates, vyberte položku Win32 Project. V textovém
poli Name zadejte jméno pro váš
nový projekt a zaškrtněte volbu Create directory for Solution, čímž zabezpečíte vytvoření samostatné složky pro vaše řešení. Když
jste se změnami spokojeni, klepněte na tlačítko OK.
Obr. 2 – Výběr typu aplikace
v průvodci
Visual C++ posléze vytvoří všechny nezbytné
soubory, které si aplikace typu Win32 DLL vyžaduje. Seznam těchto souborů si
můžete prohlédnout v Průzkumníkovi řešení (Solution Explorer). Okno
Průzkumníka řešení by se mělo nacházet v pravé horní části okna Visual C++
a jeho podoba je zachycená na obr. 3.
Obr. 3 – Okno Průzkumníka
řešení (Solution Explorer)
Nyní poklepejte na položku DLL_C++.cpp, která
se nachází ve stromové struktuře pod uzlem Source Files. Visual C++ následně otevře vybraný zdrojový soubor projektu, kterého
obsah pro vás zobrazí v okně pro zápis programového kódu (obr. 4).
Obr. 4
– Okno pro zápis programového kódu ve Visual C++
V tomto okně si můžete všimnout více
věcí, které se vám (jako programátorovi VB), můžou zdát neznámé a podivné.
Pojďme tedy pěkně popořádku a obsah okna si vysvětleme. Nuže, první dva řádky představují
komentáře, které do kódu umístil samotný Visual C++. Zapamatujte si, že každý
komentář (ve stylu jazyka C++) je uveden dvěma lomítky, které jsou symbolem pro
jednořádkové komentáře. Znamená to tedy, že když uvedete v kódu dvě
lomítka a za nimi text, tento je později kompilátorem chápán jako komentář a je
zcela ignorován.
Další nejasností je pravděpodobně tento řádek:
#include "stdafx.h"
První část výrazu #include je takzvaná direktiva preprocesoru.
Ta „říká“ preprocesoru, aby soubor s názvem „stdafx.h“ začlenil do programového
kódu projektu. Řečeno jinými slovy, když preprocesor při své práci „narazí“ na
direktivu #include, vloží obsah souboru, který tato direktiva specifikuje, do
samotného programového kódu vyvíjené aplikace. Soubor „stdafx.h“, jenž tvoří
druhou část výrazu, je tzv. hlavičkovým souborem.
|
Preprocesor je typem textového procesoru, který jistým způsobem
modifikuje zdrojový text programu ještě před samotnou kompilací (ve
skutečnosti se preprocesor používá jenom v první etapě kompilace
programu). |
Následuje definice funkce DllMain, která je vstupním bodem (entry point) do dynamické knihovny. Tuto funkci volá samotný operační systém při inicializaci a terminaci procesů a vláken. Protože v naší ukázce nebude chtít vykonávat žádné operace při uvedených činnostech, můžeme ponechat funkci DllMain v její původní podobě.
Ve všeobecnosti je dynamicky
linkovaná knihovna naplněna funkcemi, které je možné z jejího prostředí
později volat. Abyste do stávajícího kódu přidali také kód pro naší
exportovanou funkci, udělejte následovní:
extern "C" __declspec(dllexport) __stdcall int Mocnina(short
cislo)
{
return cislo*cislo*cislo;
}
Toto je zápis pro exportovanou funkci. Pod pojmem „exportovaná funkce“ se rozumí funkce, která bude v budoucnosti volána z programovacího jazyka VB .NET. Aby bylo možné tuto funkci zavolat z programu VB .NET, je zapotřebí uvedená definice funkce. Pokud odhlédneme od použití modifikátorů extern „C“, __declspec(dllexport) a volací konvence __stdcall, dostáváme se k samotné funkci. Její název je „Mocnina“ a jak je vidět, funkce má jeden parametr, kterým je proměnná typu short s názvem „cislo“.
|
V jazyce C++ se proměnné deklarují jinak než je to ve Visual
Basicu. Zde je zapotřebí nejdříve uvést datový typ proměnné a až poté samotné
jméno proměnné. |
Protože jde o
parametr funkce, je nutno jej uzavřít do kulatých závorek. Návratová hodnota
funkce je specifikována před jménem funkce; z uvedeného příkladu vidíme,
že půjde o návratovou hodnotou typu integer, jak specifikuje klíčové slovo int. Tělo každé funkce v prostředí jazyka C/C++
je uzavřeno do složených závorek. Tělem funkce se rozumí příkazy, které se mají
provést tehdy, je-li funkce zavolána. V našem případě si můžete všimnout,
že v těle funkce je jenom jediný příkaz. Tento příkaz vypočte třetí
mocninu čísla, kterou funkce při dokončení své práce vrací. Všechno, co
následuje za klíčovým slovem return představuje
návratovou hodnotu funkce. Konečně, každý příkaz v jazyku C/C++ je ukončen
nikoliv koncem řádku, nýbrž středníkem.
Obr. 5 – Výběr definičního
souboru pro export funkce z knihovny DLL
|
Při zápisu jména funkce mějte na paměti, že Visual C++ je „case
sensitive“, tedy rozlišuje malá a velká písmena ve slovech. Pokud byste
zadali místo řetězce „Mocnina“ řetězec „mocnina“, jednalo by se o zcela jinou funkci. |
Obr. 6 – Výslední podoba
souboru DEF
|
Všimněte si hvězdičky, která se nachází v záložce za jménem DEF
souboru na obr. 6. Tímto způsobem vás Visual C++ upozorňuje na skutečnost, že
obsah souboru se změnil od té doby, co jste tento soubor naposled uložili. |
Po vydání příkazu na sestavení aplikace Visual
C++ zkompiluje všechny nezbytné soubory a vybuduje jedinou dynamickou knihovnu.
Jestliže vše proběhlo tak, jak mělo, ve spodním panelu uvidíte text „Build
succeeded“. Výborně, dokázali jste vytvořit svou první dynamicky linkovanou
knihovnu!
Podíváte-li se do složky vašich projektů a
otevřete složku Debug právě vytvořeného projektu, můžete vidět knihovnu DLL
v celé její kráse tak, jak ji znázorňuje obr. 7.
Obr. 7 – Vytvořená dynamicky
linkovaná knihovna (DLL)
Abyste nemuseli později zadávat celou cestu
k vaší knihovně DLL, zkopírujte ji do systémové složky Windows
(Windows\System).
Visual Basic .NET a Visual C++ .NET
Krok 2: Využití dynamické knihovny
ve Visual Basicu .NET
Pro předvedení možností
knihovny DLL v prostředí VB nejdříve přidáme do stávajícího projektu
standardní projekt VB. Postupujte takto:
Public Declare Function Mocnina Lib
"DLL_C++.dll" _
(ByVal cislo As Short) As Integer
MessageBox.Show(Mocnina(3).ToString)
Jakmile klepnete na
tlačítko, VB .NET zavolá exportovanou funkci s názvem „Mocnina“, která
vypočte třetí mocninu čísla 3 a návratovou hodnotu zobrazí v okně zprávy
(obr. 8).
Obr. 8 – Finální podoba
spolupráce aplikace VB a knihovny DLL
Výborně, dynamicky linkovaná knihovna odvádí
svou práci na jedničku!
Abyste zmenšili velikost
výslední knihovny DLL, můžete ji také sestavit v distribučním provedení.
V tomto provedení se kód plně optimalizuje a rovněž se z něj odstraní
informace, které jsou určeny pouze pro proces odlaďování knihovny. V prostředí
Visual C++ udělejte následovní:
Obr. 9 – Výběr distribučního
provedení knihovny DLL v okně Configuration Manager
Visual C++ uskuteční sestavení dynamicky
linkované knihovny a ve stávající složce projektu vytvoří další složku
s názvem „Release“. Ve složce „Release“ se nachází knihovna DLL,
připravená na distribuční proces. Abyste měli lepší představu o velikosti
knihovny DLL, podívejte se na obr. 10, který znázorňuje velikost knihovny DLL
určené pro odlaďování a pro distribuci.
Obr. 10 – Porovnání velikosti
variant provedení knihovny DLL
Věřím, že vás uvedená problematika zaujala a
rozšířila vaše programátorské znalosti.
Ján Hanák