Teh DLL-opas VERSIO 1.1

Muu yhteisön välinen keskustelu.
User avatar
esa94
Guru
Posts: 1855
Joined: Tue Sep 04, 2007 5:35 pm

Teh DLL-opas VERSIO 1.1

Post by esa94 »

Iltaa, CB-yhteisö! Ajattelin ilahduttaa teitä julkaisemalla monien kaipaamaan, äärimmäisen näppärän oppaan, nimeltään:

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
Ellet osaa C:tä tai C++:aa, suosittelen, että luet tämän oppaan

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)
Täten voimmekin päätellä, että ulosmenevän muistipalan ollessa tyyppiä int*, halutaan ulosmenevän muistipalan koon olevan vähintään 4 tavua. Tämä kannattaa varmistaa, ettet vahingossa kirjoita varatun muistin yli. Esimerkissäni ohjelma heittää tässä tilanteessa virheilmoituksen, eikä anna kirjoittaa muistiin mitään.

Funktiota kutsutaan CB:stä komennolla

Code: Select all

CallDLL "DLL.dll", "Funktio", memBlock, memBlock2
Jossa memBlock on sisäänmenevä muistipala (parametri 1) ja memBlock2 vastaavasti ulostuleva (parametri 3).

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

dll.cpp

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;

    }
}

Ai, mitäkö tämä koodi tekee? Senkö halusit tietää? Selitetään!

Ä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 );
muotoon

Code: Select all

DLL_EXPORT void GrabLol( const int *_in, int in_size, int *_out, int out_sz );
Se siis vain yksinkertaistaa koodausta. HUOM! Funktion määrittelyn alussa on pakko olla DLL_EXPORT! (Tai se monimutkaisempi muoto)

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ä.
anttipanda wrote:
EDIT:

Näemmä Visual C++ ei käännä tuota koodia sellaisenaan, merkkijonot tarvitsevat L-prefiksin.

Code: Select all

...
MessageBox( NULL, L"Error! Insufficient reserved memory!\nOutput memblock size under 4 bytes!", L"Error!", NULL );
...
[/edit]
Jos kääntyi, kokeile sitä! Tässä koodinpätkä, joka sinun tulee laittaa samaan kansioon DLL:n kanssa nopeaa testausta varten.

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 
Koottuja linkkejä ja sälää

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:
Last edited by esa94 on Mon Mar 29, 2010 5:26 pm, edited 4 times in total.
Jani
Devoted Member
Posts: 741
Joined: Fri Oct 31, 2008 4:53 pm

Re: Teh DLL-opas

Post by Jani »

Miten se käännetään cpp:stä DLL:älläksi?
Dead men tell no tales. Also, Python rocks!
Codegolf: 99 bottles of beer (oneliner) - Water map partition
Aavesoturi
Active Member
Posts: 163
Joined: Fri Aug 31, 2007 7:07 pm
Location: Helsinki
Contact:

Re: Teh DLL-opas

Post by Aavesoturi »

Hyvä että on taas dll-opas, kun marcoderin tekemä on offline.

Jos ei osaa tai halua käyttää C++:aa, ni osoitteesta http://jouluserver.com/~aave/cb/fbdll.html löytyy pieni kirjoittamani opas, jossa dll:iä tehdää cb:lle FreeBasic-kielellä ( http://www.freebasic.net ).

Pari tuollaista fb:llä tehtyä dll:ää löytyy osoitteesta http://jouluserver.com/~aave/cb/ .
anttipanda
Active Member
Posts: 248
Joined: Mon Aug 27, 2007 9:23 pm
Location: Oulu

Re: Teh DLL-opas

Post by anttipanda »

Jani wrote:Miten se käännetään cpp:stä DLL:älläksi?
Tämä on yleensä se mikä C++-ohjelmointia aloitellessa on kompastuskivenä; miten komentaa kääntäjää ja muita liittyviä ohjelmia. Voisiko oppaan tekijä lisätä tämän tärkeän asian mukaan, pelkät koodit eivät merkitse mitään jos niitä ei osaa kääntää. Eli esimerkkiprojektifileä yms. kehiin, tai ainakin kääntäjän ja linkkerin asetuksia. Onhan tuossa lauseella mainittu että tulee tehdä DLL-projekti, mutta aika ylimalkaista.
OoO
User avatar
esa94
Guru
Posts: 1855
Joined: Tue Sep 04, 2007 5:35 pm

Re: Teh DLL-opas

Post by esa94 »

Valista meitä, antti, jos osaat! Itse en saa GCC:llä komentoriviltä kääntämällä aikaiseksi kuin komentoriviohjelmia.
Koodiapina
Forum Veteran
Posts: 2396
Joined: Tue Aug 28, 2007 4:20 pm

Re: Teh DLL-opas

Post by Koodiapina »

Oliskohan tästä apua?
m1c
Member
Posts: 65
Joined: Tue Aug 28, 2007 5:10 pm
Location: \o

Re: Teh DLL-opas

Post by m1c »

Uuden dll-projektin voi luoda näin visual c++:ssä (9 EE) jos tästä nyt on jotain apua: http://mikkis.net/dll-vcc.png
anttipanda
Active Member
Posts: 248
Joined: Mon Aug 27, 2007 9:23 pm
Location: Oulu

Re: Teh DLL-opas

Post by anttipanda »

esa94 wrote:Valista meitä, antti, jos osaat! Itse en saa GCC:llä komentoriviltä kääntämällä aikaiseksi kuin komentoriviohjelmia.
Valista itse, sinähän se teh opastaja olet ;)

Eipä ole itsellä muista kokemusta kuin Visual Studiosta ja Carbidesta näiden DLL-projektien teossa. Visual Studio tuskin on monen saatavissa (muistaakseni siinä oli ihan DLL-projekti valittavissa), eikä Carbidella kuitenkaan täällä olijoista kuitenkaan mitään tee.

Visual C++ näyttäisi sisältävän DLL projektin. File|New Project...|Application Settings -> DLL Project, Empty Project. Sinne sitten vain lisäämään filejä.
EDIT:

Näemmä Visual C++ ei käännä tuota koodia sellaisenaan, merkkijonot tarvitsevat L-prefiksin.

Code: Select all

...
MessageBox( NULL, L"Error! Insufficient reserved memory!\nOutput memblock size under 4 bytes!", L"Error!", NULL );
...
[/edit]
OoO
User avatar
esa94
Guru
Posts: 1855
Joined: Tue Sep 04, 2007 5:35 pm

Re: Teh DLL-opas

Post by esa94 »

anttipanda wrote:
EDIT:

Näemmä Visual C++ ei käännä tuota koodia sellaisenaan, merkkijonot tarvitsevat L-prefiksin.

Code: Select all

...
MessageBox( NULL, L"Error! Insufficient reserved memory!\nOutput memblock size under 4 bytes!", L"Error!", NULL );
...
[/edit]
Minulla taas ei GCC käännä sitä noiden L-kirjaimien kanssa. Siksi ne puuttuvat koodista. :P
anttipanda
Active Member
Posts: 248
Joined: Mon Aug 27, 2007 9:23 pm
Location: Oulu

Re: Teh DLL-opas

Post by anttipanda »

esa94 wrote:Minulla taas ei GCC käännä sitä noiden L-kirjaimien kanssa. Siksi ne puuttuvat koodista. :P
Heh, hyvä meininki. Tuo voi kyllä johtua kääntäjän tai linkkerin asetuksista.
OoO
Guest

Re: Teh DLL-opas

Post by Guest »

Mites tuohon saa useampia arvoja sisään ja ulos. Kun cb:n memblockiin laittaa 2 kokonaislukua niin tuo ei avaa kuin ensimmäisen.
Myös useammalle ulostuloarvolle olisi käyttöä.
Jani
Devoted Member
Posts: 741
Joined: Fri Oct 31, 2008 4:53 pm

Re: Teh DLL-opas

Post by Jani »

Vieras wrote:Mites tuohon saa useampia arvoja sisään ja ulos. Kun cb:n memblockiin laittaa 2 kokonaislukua niin tuo ei avaa kuin ensimmäisen.
Myös useammalle ulostuloarvolle olisi käyttöä.
IRC:ssä neuvottiin että toinen intti voidaan lukea näin:

Code: Select all

(prt+4)
Eli ptr tilalle pointterisi.
Dead men tell no tales. Also, Python rocks!
Codegolf: 99 bottles of beer (oneliner) - Water map partition
skorpioni-cb
Advanced Member
Posts: 364
Joined: Wed Dec 03, 2008 3:48 pm
Location: Turku

Re: Teh DLL-opas

Post by skorpioni-cb »

Miten voi muodostaa cpp ja h tiedostoista dll tiedoston?
En tiedä, mitä tiedän, mutta tiedän ettei se ole mitään kaunista.

I know not what I know, but I do know that it's not beautiful.
JATothrim
Tech Developer
Tech Developer
Posts: 606
Joined: Tue Aug 28, 2007 6:46 pm
Location: Kuopio

Re: Teh DLL-opas

Post by JATothrim »

skorpioni-cb: Käännät ne käyttäen jotain vapaasti saatavilla olevaa kääntäjää. Esim MinGW (joka on siis GCC wintoosalle) paketilla onnistuu. Hyvä IDE auttaa asiassa paljon. Esim. itse käytän Code:Blocks:ia.
EDIT:

Muutin tätä viestiä koska närkästyneitä henkilöitä alkoi olla liikaa, pahoitteluni. Ja tässä sama pätkä todella pienellä:
(hyminää... (olen jo lähes 100% C++/IDE konkari) :P :lol: tirsk. ketjun "pro-maisuus" on alle nollan..)

Last edited by JATothrim on Sat Nov 14, 2009 9:57 pm, edited 1 time in total.
-On selkeästi impulsiivinen koodaaja joka...
ohjelmoi C++:lla rekursiivisesti instantioidun templaten, jonka jokainen instantiaatio instantioi sekundäärisen singleton-template-luokan, jonka jokainen instanssi käynistää säikeen tulostakseen 'jea'.
User avatar
Dibalo
Advanced Member
Posts: 298
Joined: Mon Aug 27, 2007 8:12 pm
Location: Espoo, Finland
Contact:

Re: Teh DLL-opas

Post by Dibalo »

JATothrim wrote:(hyminää... (olen jo lähes 100% C++/IDE konkari)...
Aika kova väite... Kannattaa harkita jatkossa ennen kuin moisia laukoo...
The darkest spells can be found from
http://tunkkaus.blogspot.fi
User avatar
esa94
Guru
Posts: 1855
Joined: Tue Sep 04, 2007 5:35 pm

Re: Teh DLL-opas

Post by esa94 »

Herätys, viestiketju!

Kirjoitin teidän kaikkien aloittelevien C:llä ja C++:lla DLL:iä koodaavien iloksi pienen headerin, joka saattaa auttaa hommassa. Ohjeet löytyvät itse filusta, joka alla pastena.

Tallentakaa vaikkapa nimellä cbDLL.h ja includetkaa jos tarve vaatii.

Sisältää seuraavat makrot:

CB_FUNCTION( funktionnimi ) - voit vain läntätä makron DLL:si filuun, eikä sinun tarvitse välittää funktion määrittelystä. Funktionnimi on myös nimi, jolla pääset funktioon CB:stä käsin käsiksi.

INPUT_MEMBLOCK, OUTPUT_MEMBLOCK, INPUT_MEMBLOCK_SIZE, OUTPUT_MEMBLOCK_SIZE - Aika itsestäänselviä. Toimivat vain funktiossa, jonka määrittely on sama kuin CB_FUNCTION:lla määritellyn funktion

POKE<tietotyyppi>, PEEK<tietotyyppi> - Toimivat kuin CB:n vastaavat funktiot. Helpottanee käyttöä jos et itse jaksa osoittimilla kikkailla. HUOM! VIRHETARKISTUKSIA EI OLE, ÄLÄ LUE / KIRJOITA MUISTIPALAN YLI!!!

Jos jostain syystä koodinne alkaa heittämään erroria tuon headerin includettamisen jälkeen, älkää valittako missään muualla kuin tässä topicissa. Todennäköisimmin virhe on minun.

Huomatkaa kiva tietotyyppitaulukko headerin loppupäässä.

cbDLL.h
<uusi versio alempana>

Unohtakaa nauttia koodistani.
EDIT:

Voisi kyllä itse oppaankin piakkoin uusia... Vai haluaako joku muu?

Last edited by esa94 on Sat Nov 12, 2011 3:07 pm, edited 1 time in total.
User avatar
esa94
Guru
Posts: 1855
Joined: Tue Sep 04, 2007 5:35 pm

Re: Teh DLL-opas VERSIO 1.1

Post by esa94 »

Anteeksi tuplapostaus, mutta tein uuden version cbDLL.h:sta, sekä havaintoesimerkin, miten tuota käytetään ja miten saat kutsuttua CB:lle tehtyä funktiota sen avulla C++:lla.

Toisin sanoen älkää välittäkö mitään edellisestä lauseesta vaan ladatkaa vain seuraava liitetiedosto:
cbDLLAPI.zip
Paketti.
(143.71 KiB) Downloaded 387 times
Tiedosto on siis zip-arkisto, joka sisältää kaksi binääriä, LibTest.exe ja cbDLL.dll. Molempien kääntämiseen tarvittavat lähdekoodit on sisällytetty pakettiin. Periaatteessa LibTest toimisi myös *NIX-järjestelmissä, ellei cbDLL olisi yksionomaan Windowsille koodattu.

Binäärit on käännetty MinGW:n gcc ja g++ -kääntäjillä Windows Vista Home Basicin 32-bittisellä versiolla (Onko niitä muita?) varustetulla läppärillä. Toimitetun makefilen käyttämiseen tarvitset MSYS:n asennettuna koneellesi.

Ellet tietysti cross-compilaa Linuxilta :D
Latexi95
Guru
Posts: 1166
Joined: Sat Sep 20, 2008 5:10 pm
Location: Lempäälä

Re: Teh DLL-opas VERSIO 1.1

Post by Latexi95 »

Pahoittelen topicin nostamista.
Esa: Viitsitkö korjata cbDLLAPIn POKEINTissä olevan virheen. Sieltä puuttuu "*" - merkki "int" - sana jälkeen. Pirullinen typo sillä ei välttämättä aiheuta kääntäjältä virheilmoitusta, mutta tehokkaasti estää ohjelman toiminnan.

EDIT:

Hemmetti. Kirjoitin PEEKINT vaikka piti kirjoittaa POKEINT... :oops:

User avatar
esa94
Guru
Posts: 1855
Joined: Tue Sep 04, 2007 5:35 pm

Re: Teh DLL-opas VERSIO 1.1

Post by esa94 »

Voisi kai tuon korjata, jos joku sitä nyt käyttää. Odotapa hetki.
EDIT:

Code: Select all

#ifndef __GUARD_CBAPI__
#define __GUARD_CBAPI__

#if defined(C_PLUS_PLUS) || defined(__cpluplus)
#define CDEF extern "C"
#else
#define CDEF
#endif

#define _WIN32_WINNT 0x0501 /* Windows XP:n ominaisuudet käyttöön */

#define CB_FUNCTION(__funcname__) CDEF __declspec(dllexport) void __funcname__(const void *_in, int in_size, void *_out, int out_sz)
#define INPUT_MEMBLOCK _in
#define OUTPUT_MEMBLOCK _out
#define INPUT_MEMBLOCK_SIZE in_sz
#define OUTPUT_MEMBLOCK_SIZE out_sz
#define POKEBYTE(__mem__, __byte__, __value__) ((*((unsigned char *) (((char *) __mem__) + __byte__))) = (unsigned char) __value__ )
#define POKESHORT(__mem__, __byte__, __value__) ((*((unsigned short int*) (((char *) __mem__) + __byte__))) = (unsigned short int) __value__)
#define POKEINT(__mem__, __byte__, __value__) ((*((int *) (((char *) __mem__) + __byte__))) = (int) __value__)
#define POKEFLOAT(__mem__, __byte__, __value__) ((*((float *) (((char *) __mem__) + __byte__))) = (float ) __value__)
#define PEEKBYTE(__mem__, __byte__) (*((unsigned char *) (((char *) __mem__) + __byte__)))
#define PEEKSHORT(__mem__, __byte__) (*((unsigned short int *) (((char *) __mem__) + __byte__)))
#define PEEKINT(__mem__, __byte__) (*((int *) (((char *) __mem__) + __byte__)))
#define PEEKFLOAT(__mem__, __byte__) (*((float *) (((char *) __mem__) + __byte__)))

/*
 * Makrojen käyttö:
 *
 * CB_FUNCTION( funktionnimi ) käytetään funktion tavallisen määrittelytavan (void funktionnimi ja niin edelleen) tilalla
 * Esimerkki käytöstä:
 * CB_FUNCTION( esimerkkifunktio )
 * {
 *
 * 	<tähän funktion koodi>
 *
 * }
 *
 * INPUT_MEMBLOCK on sama kuin _in
 *
 * OUTPUT_MEMBLOCK on sama kuin _out
 *
 * INPUT_MEMBLOCK_SIZE on sama kuin in_sz
 *
 * OUTPUT_MEMBLOCK_SIZE on sama kuin out_sz
 *
 * POKE* ja PEEK* -makrot samoja kuin CB:n vastaavat funktiot
 *
 * Tietotyyppimuunnokset
 * ------------------------------------------
 * CoolBasic | C ja C++
 * ------------------------------------------
 * Integer   | int / int32_t
 * Short     | unsigned short int / uint16_t
 * Byte	     | unsigned char / uint8_t
 * Float     | float
 * String    | unsigned char * (Ks. HUOM)
 * ------------------------------------------
 * HUOM! Merkkijonojen käsittely on C:ssä
 * erilainen kuin CoolBasicissa. C:n merkki-
 * jonot ovat osoittimia merkkijonon alkuun,
 * eivätkä ole "varsinaisia" tietotyyppejä.
 * ------------------------------------------
 *
 * POKEBYTE( muistipala, tavuja muistipalan alusta, arvo ) 
 * PEEKBYTE( muisti, tavuja )
 * POKESHORT( muisti, tavuja, arvo )
 * PEEKSHORT( muisti, tavuja )
 * POKEINT( muisti, tavuja, arvo )
 * PEEKINT( muisti, tavuja )
 * POKEFLOAT( muisti, tavuja, arvo )
 * PEEKFLOAT( muisti, tavuja )
 *
 * Toiminta perustuu siihen, että ensin osoitin muutetaan 
 * osoittimeksi char:iin (tavun tarkkuus), siirrytään
 * haluttu määrä tavuja eteenpäin, muunnetaan osoittimen
 * tietotyyppi halutuksi ja kirjoitetaan data osoittimen
 * osoittamaan muistiosoitteeseen.
 * Prosessi on muuten sama PEEK* -makroilla, mutta
 * kirjoitus jää pois
 */


typedef void (*cbFunction)(const void *, int, void *, int);
/*
 * Jokaisen CB:lle näkyvän funktion tulee vastata tätä tietotyyppiä.
 * Tämä mahdollistaa myös funktio-osoittimien pyörittelyn DLL:n puolella tarpeen vaatiessa.
 *
 * HUOM! Jos käytät C++:aa, tulee ottaa huomioon että funktionimen täytyy olla "puhdas".
 * C++-kääntäjä muuntaa aina funktioiden nimet niiden argumenttien ja palautusarvon mukaan, minkä vuoksi jokaista CB:lle tarkoitettua funktiota tulee edeltää extern "C"-määritys.
 *
 * Asian voi korjata yksinkertaisesti käyttämällä CB_FUNCTION -makroa funktion määrittelyyn tai CDEF-makroa oman funktiomäärittelysi edellä.
 */

#endif
[/edit]
User avatar
Konstaduck
Advanced Member
Posts: 267
Joined: Sat Dec 17, 2011 3:09 pm
Location: Nurmijärvi, Finland
Contact:

Re: Teh DLL-opas VERSIO 1.1

Post by Konstaduck »

Topicciin on postattu 4 kuukautta sitten. Aletaas nyt herättää sitä

Miten saisin tuon Visual C++:n toimimaan? Kääntäjä ilmoittaa aina, että virhe siellä, virhe täällä. Ärsyttävää :(
Konstaduck.net
<Ize> Pitäs tehä allekirjotus..
<Ize> Vois keksiä jonkin nasahtavan sanonnan..
<Ize> Siitä tulis upea legenda ja kaikki vaihtaisivat allekirjoituksensa siihen.
<Ize> Ehkä ei kuitenkaa...
Post Reply