Teh pieni DLL-opas V1.1
1. Alkusanat ja hieman teoriaa
Tämä opas on suunnattu C:tä tai C++:aa osaaville ohjelmoijille. Suosittelen myös käyttämään jotakin IDEä, esimerkiksi Code::Blocks, Visual C++ tai CodeLite käyvät hyvin. Jos osaat jo kääntää komentoriviltä, tuskin tarvitsetkaan tätä opasta, mutta GCC:llä sen pitäisi hoitua seuraavasti:
Code: Select all
gcc -Wall -shared -o <dllnimi>.dll
Oppaan uudelleenkirjoitusta suunnittelen, siitä tuo V1.1. Osa tiedoista on wanhaa ja huonoa tekstiä/koodia, mutta pitäisi toimia. Kysykää minulta mitä tarkoitan, jos ette ymmärrä.
WANHAA TEKSTIÄ
Tämä opas syntyi oman pikku DLL-harjoitukseni seurauksena, jonka sainkin vasta tänä iltana valmiiksi. Zero auttoi minua ircin kautta ongelmassa palautusarvon kanssa. Mainitsen jo nyt, että CB:llä kutsuttavalla funktiolla on neljä parametriä, jotka ovat:
- Osoitin sisääntulevaan muistipalaan (Todennäköisesti hyödyllisin on const int*, jota minä oppaassa käytän)
- Sisääntulevan muistipalan koko tavuina (int)
- Osoitin ulosmenevään muistipalaan (Todennäköisesti hyödyllisin on int*, jota minä oppaassa käytän)
- Ulosmenevän muistipalan koko tavuina (int)
Funktiota kutsutaan CB:stä komennolla
Code: Select all
CallDLL "DLL.dll", "Funktio", memBlock, memBlock2
Koodia!
Perusasioista liikkeelle. Kääntääksesi ohjelman tarvitset vain yhden tiedoston, mutta DLL:ää kääntäessäsi kaksi. Nämä tiedostot kannattaa nimetä yksinkertaisesti dll.cpp (lähdekoodi) ja dll.h (otsikko). Tämän pitäisi helpottaa koodaamistasi selvästi.
Oletan, että käytät jotakin IDE:ä, kuten Code::Blocksia tai Dev-C++:aa, muun muassa siksi, etten itse osaa kääntää DLL:iä komentoriviltä. (Älä huoli, Grandin postaama linkki löytyy viestin alalaidasta sekä Grandin viestistä) Aloittaaksesi koodaamisen, aloita DLL-projekti, (tai tyhjä projekti ja Build Targetiksi DLL, tosin tämä on edistyneemmille) jonka tallennat mihin haluat. Seuraavaksi itse koodaamiseen.
Avaa sekä dll.h, että dll.cpp. Korvaa niiden sisältö tällä:
dll.h
Code: Select all
#ifndef _DLL_H_
#define _DLL_H_
#include <stdio.h>
#include <windows.h>
#define DLL_EXPORT extern "C" __declspec( dllexport )
DLL_EXPORT void GrabLol( const int *_in, int in_size, int *_out, int out_sz );
#endif
Code: Select all
#include "dll.h"
DLL_EXPORT void GrabLol( const int *_in, int in_size, int *_out, int out_sz ) {
if ( out_sz < 4 ) { MessageBox( NULL, "Error! Insufficient reserved memory!\nOutput memblock size under 4 bytes!", "Error!", NULL ); }
int in = *_in;
if ( in == 1337 ) {
*_out = 715517;
}
else {
*_out = 80085;
}
}
Älä välitä #ifndef _DLL_H_ ja #define _DLL_H_ -riveistä, ne vain varmistavat, ettei tiedostoa sisällytetä useasti. Se nimittäin saattaisi sekoittaa kääntäjän.
Seuraavilla riveillä sisällytetään tarvittavat kirjastot. <Ei se windows.h olekaan pakollinen, unohtakaa, perhana.>
#define DLL_EXPORT extern "C" __declspec( dllexport ) yksinkertaistaa koodausta sillä sen avulla voi muuttaa koodinpätkän
Code: Select all
void extern "C" __declspec( dllexport ) GrabLol( const int *_in, int in_size, int *_out, int out_sz );
Code: Select all
DLL_EXPORT void GrabLol( const int *_in, int in_size, int *_out, int out_sz );
Tuo äsken mainittu koodinpätkä on funktiosi prototyyppi. Ellet tiedä, mikä se on, en rupea sitä selittämään. Sen sijaan lue asiasta alussa mainitsemastani oppaasta. Nyt sinun pitäisi voida päätellä, mitä tiedoston dll.cpp koodi tekee. Ellet, niin se tarkistaa, että ulosmenevän muistipalan koko on ainakin 4 tavua, ja asettaa siihen luvun, riippuen siitä, onko sisääntuleva arvo 1337.
Huomaa, että DLL ei sisällä main-funktiota.
Käännä DLL. Kääntyikö se? Jos ei, kerro saamastasi virheestä tässä viestiketjussa. Kerro samalla käyttämäsi IDE (Jos käytät) ja kääntäjä.
Jos kääntyi, kokeile sitä! Tässä koodinpätkä, joka sinun tulee laittaa samaan kansioon DLL:n kanssa nopeaa testausta varten.anttipanda wrote:EDIT:Näemmä Visual C++ ei käännä tuota koodia sellaisenaan, merkkijonot tarvitsevat L-prefiksin.
[/edit]Code: Select all
... MessageBox( NULL, L"Error! Insufficient reserved memory!\nOutput memblock size under 4 bytes!", L"Error!", NULL ); ...
Code: Select all
memBlock = MakeMEMBlock( 4 )
memBlock2 = MakeMEMBlock( 4 ) 'Jos muutat luvun pienemmäksi kuin 4, saat virheilmoituksen!
PokeInt memBlock, 0, 1337
CallDLL "DLL.dll", "GrabLol", memBlock, memBlock2
Print PeekInt( memBlock2, 0 )
WaitKey
Linkkilistaus:
http://www.nic.funet.fi/c++opas/ -- Perusopas
http://mikkis.net/dll-vcc.png -- DLL-Projekti VC++:ssa
http://sig9.com/node/35 -- Kääntäminen komentoriviltä
Muu: