Toon posts:

[VB] Modules laden tijdens runtime

Pagina: 1
Acties:
  • 164 views sinds 30-01-2008
  • Reageer

Verwijderd

Topicstarter
Ik ben bezig in Visual Basic een programma te maken om LCD's aan te sturen. Ik heb nu dus ook een programma met alle basisfuncties (printText(), Clear(), enz). Maar nu wil ik het programma zó maken dat je een basisprogramma hebt waar je later modules in kunt laden die dan bijvoorbeeld zijn om Winamp-functionaliteit of spelletjes toe te voegen aan het LCD-programma, maar hiervoor moet je het programma niet opnieuw hoeven te compilen. Gewoon modules dus, maar dan modules die je tijdens runtime laat laden.
Is dat mogelijk met Visual Basic en zo ja, hoe?
Ik heb de search gebruikt, niks gevonden, en ook Google had niets zinnigs te melden.
Alvast bedankt :)
Jaja, VB sux enzo, maar het is de enige taal waar ik redelijk een GUI in kan proggen

  • MichelVH
  • Registratie: Oktober 2001
  • Laatst online: 01-08 09:33
Kijk eens op Planet source Code daar staan een aantal aardige voorbeelden tussen :)

Don't be afraid of the dark, be afraid of what it hides


Verwijderd

Topicstarter
Ik heb op Planet Source Code wat code gevonden om een DLL te laden, maar hoe roep ik vanuit een DLL een (public) functie van het 'main'-programma aan? Of kan dat niet?

  • Flard
  • Registratie: Februari 2001
  • Laatst online: 20-08 14:34
zoek daar anders 's op plug-in (of plugin)...
ik heb daar ooit een hele mooie code waarmee je precies kunt doen wat jij wilt

  • shades
  • Registratie: September 2001
  • Laatst online: 10-08 15:01

shades

huh ?

Het is niet zo heel ingewikkeld.

Hetgeen je in een dll wilt hebben plaats je eerst in een gewone module..

Daarna gooi je heel de zooi in een classmodule en dan moet je wat dingen doen met get en set properties. Vars zetten naar de class doe je met public vars.

Als het dan nog steeds werkt open je een nieuwe project als activex dll.
Daar copy-past je de inhoud van de classmodule in

Dan compilen

Dan dll registeren met regsrv

Daarna kan je in vb via project->references je dll toevoegen

Als het goed is zie je dan in je objectbrowser (F2) de logische naam van je dll staat (TestDll ofzo)

Dan doe je iets van Dim test as new TestDll

En dan kan je test gebruiken

test.properties enzo

Beetje snel maar global werkt het wel ongeveer zo...

https://k1600gt.nl


  • Korben
  • Registratie: Januari 2001
  • Laatst online: 14-11-2025

Korben

() => {};

Je kunt in VB niet echt runtime DLLs laden, omdat je daarvoor pointers moet kunnen gebruiken, en dat kan niet. Je kunt wel vrolijk een DLL laden met LoadLibraryEx, maar om de functies te benaderen gebruik je GetProcAddress(), die het geheugenadres van de entry point van de functie teruggeeft. Helaas pindakaas, maar dat is alleen nuttig in C en Delphi en dergelijken. In VB kun je daar geen hol mee. Er zijn inderdaad wel manieren om het wel te doen, maar dan kijk je naar third party components die in C++ zijn geschreven, en bovendien zit je met het meegeven van parameters. Je moet dan of alleen functies zonder parameters aanroepen, maar dat is vrij nutteloos, of je moet voor elke denkbare combinatie van parametergroottes (want daar draait het om) functies gaan schrijven. Iets wat de footprint van zo'n component niet ten goede komt. Bovendien ben je dan afhankelijk van dat component, wat uitermate frustrerend kan zijn als er net een bug zit in het onderdeel wat jij nodig hebt. Conclusie: plug-ins in VB, don't even think about it.

.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
Dit zipje dat ik effe snel in elkaar heb geflanst bewijst het tegendeel denk ik...

Niet dat het heel erg mooi is, maar redelijk modulair en goed aan te passen naar wat je zelf wilt...

/edit/
effe korte uitleg:
De main app kijkt in de /plugins directory naar het bestand "index.xml", daarin worden alle plugins opgesomd (dus ja, je kunt niet zomaar een directory met .dll's aanwijzen et voila).

Het xml bestand bevat informatie over de plugins (naam, omschrijving en whatever)

Het programma laadt alle plugins met het "Startup" attribute op "True" bij het opstarten. Andere plugins kunnen apart gestart worden.

Effe een boel notes:
* Hier zit geen check in of een plugin al geladen is
* Hier zit uberhaupt amper error-handling in
* Noch geen commentaar ;)
* Er moet nog een hoop aan gebeuren voordat het echt vriendelijk is om te gebruiken als programmeur
* Alle plugin's (.dll's) dienen geregistreerd te zijn met regsvr, dus dat dient de installatie van de dll's voor zijn rekening te nemen
* enzovoorts, enzovoorts

Maar je kunt dus duidelijk wel (een vorm van) plugins gebruiken. Dit is alleen bedoeld als een POC (Proof Of Concept) en ik sta dus niet in voor allerlei enge gevolgen.

Alle flames / gezeik over mijn code / gezeik over whatever / requests als "kun je het afmaken" of "wanneer komt v2.0?" gaan direct naar /DEV/NULL ;)

[ Voor 78% gewijzigd door RobIII op 02-04-2003 02:32 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • DukeMan
  • Registratie: Mei 2000
  • Niet online
Kijk eens op:

GoT 1 of
GoT 2

Staat denk ik wel wat zinnigs in voor je

  • Korben
  • Registratie: Januari 2001
  • Laatst online: 14-11-2025

Korben

() => {};

RobIII schreef op 02 april 2003 @ 02:25:
Dit zipje dat ik effe snel in elkaar heb geflanst bewijst het tegendeel denk ik...
code:
1
rm -f /dev/null

;)

Het bewijst slecht gedeeltelijk het tegendeel. Ja, je laadt plug-ins, maar de uitvoering van functies binnen die plugins doe je niet zelf, dat wordt door de DOM afgehandeld. Bovendien moet je perse een xml bestand ervoor hebben, en een XML parser (laat dat nou toevallig niet standaard aanwezig zijn onder Windows 95... :)). Bovendien zie ik alleen dat je een plugin 'runt' (wat je trouwens maar één keer tegelijk kunt doen, maar... oh ja, ik zou niet zeiken... :P), niet dat je zelf functies aanroept of parameters meegeeft, iets wat toch best handig is als je plugins gebruikt.

In C/C++ is het allemaal zoveel mooier en eleganter...
C++:
1
2
3
4
5
6
7
8
9
10
11
// plugin laden (erg veel werk...)
HMODULE hDLL = LoadLibraryEx("plugins/aPlugin.dll", NULL, 0);

// functie opzoeken
void (*aProc)() = (void (*)()) GetProcAddress(hDLL, "pluginProc");

// en het mooiste, extreem ubersnelle flexibele code, iets wat je NOOIT in VB zult kunnen:
aProc();

// en de nodige clean-up
FreeLibrary(hDLL);

.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?


  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 18-08 22:57

Gerco

Professional Newbie

Mja, dat C (geen ++) voorbeeld is duidelijk en het illustreert inderdaad iets wat in puur VB niet mogelijk is. Daarvoor hebben we echter op www.pscode.com een prachtig programmatje wat inline assembly in VB toestaat, waardoor dit soort leuke truuckjes WEL kunnen.

En als je Assembly eng vind, zoek je op datzelfde pscode gewoon even naar de Compile Controller, waarmee je gewoon een (C) object module (.obj) in je VB executable kan linken en hetzelfde kan bereiken.

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


  • Korben
  • Registratie: Januari 2001
  • Laatst online: 14-11-2025

Korben

() => {};

Gerco schreef op 02 April 2003 @ 15:07:
Mja, dat C (geen ++) voorbeeld is duidelijk en het illustreert inderdaad iets wat in puur VB niet mogelijk is.
Het is wel C++, omdat je in C het resultaat van GetProcAddress() niet zou hoeven casten van een FARPROC. :)
Daarvoor hebben we echter op www.pscode.com een prachtig programmatje wat inline assembly in VB toestaat, waardoor dit soort leuke truuckjes WEL kunnen.
Juist. Daarvoor moet je dus 'ff' inline assembly kennen. En als je een beetje ingewikkelde code hebt, heb je te maken met stack unwind handlers en multiple entry points en dergelijke. Not good.
En als je Assembly eng vind, zoek je op datzelfde pscode gewoon even naar de Compile Controller, waarmee je gewoon een (C) object module (.obj) in je VB executable kan linken en hetzelfde kan bereiken.
Waarmee je dus nooit run-time kunt testen, wat een groot deel van de flexibiliteit van VB wegneemt, imo.

Waarmee we uiteindelijk tot de conclusie komen dat:
[list]
• VB zelf niet geschikt is voor een degelijke proprietary plug-in architectuur
• de programma's die dat wel mogelijk maken de drie letters RAD, het belangrijkste kenmerk van VB, op brute wijze verkrachten.

.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?


Verwijderd

Waarom zou je niet zelf een interpreter schrijven alvast in dat programma, zodat je later in je plugins alleen maar hoeft aan te geven wat je programmatje moet doen, waar hij zn data vandaan haalt en hoe hij het op het scherm tovert?

  • Korben
  • Registratie: Januari 2001
  • Laatst online: 14-11-2025

Korben

() => {};

Verwijderd schreef op 03 April 2003 @ 01:18:
Waarom zou je niet zelf een interpreter schrijven alvast in dat programma, zodat je later in je plugins alleen maar hoeft aan te geven wat je programmatje moet doen, waar hij zn data vandaan haalt en hoe hij het op het scherm tovert?
Hier kun je heel veel redenen voor verzinnen. Eén van die redenen kan performance zijn. Alhoewel het zowiezo een slecht idee is om voor VB te gaan als je op performance hamert (nofi, het is zo), is wat jij beschrijft een interpreter binnen een interpreter. Als je P-code gebruikt. Maar zelfs dan, het is niet makkelijk om een snelle, effectieve interpreter te schrijven. En al helemaal niet met de technische onmogelijkheden die VB heeft. En zelfs al schrijf je de snelste interpreter ter wereld, dan nóg kan die met geen mogelijkheid op tegen geoptimaliseerde gecompileerde code. En ander probleem kan zijn dat er simpelweg geen tijd is om in feite een nieuwe scriptingtaal te verzinnen. Het probleem hier is dat je niet alleen te maken hebt met het schrijven van de logica om de taal te interpreteren, je moet ook nog eens de taal zelf verzinnen. En het lijkt zo makkelijk, maar je ziet heel makkelijk dingen over het hoofd. En er zijn gewoon dingen die, wederom door de technische limitaties van VB, niet efficiënt te implementeren zijn.

.oisyn: Échte programmeurs haten PHP met een passie. Ben jij soms geen echte programmeur?


Verwijderd

het is vrij eenvoudig zelf ff een plugin frameworkie samen te gooien in vb, ik gebruik dit al jaren en werkt prima, en zie ff niet waarom je C++ of ASM zou moeten gebruiken...?

  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 18-08 22:57

Gerco

Professional Newbie

Verwijderd schreef op 03 april 2003 @ 11:04:
het is vrij eenvoudig zelf ff een plugin frameworkie samen te gooien in vb, ik gebruik dit al jaren en werkt prima, en zie ff niet waarom je C++ of ASM zou moeten gebruiken...?
Als je dan gelijk even uitlegt hoe dat dan zo eenvoudig is hebben we er allemaal wat aan.

Ik heb weleens een stukje code gezien die het deed met ActiveX dll's die on the fly even geregistreerd werden en een IPlugin interface implementeerden. Dat is bij mijn weten de enige goede manier om het met VB aan te pakken. On the fly registreren is trouwens niet nodig, dat kan ook bij de "installatie" van de plugin. Ik vind het alleen een beetje smerig om je ActiveX object lijst te gaan vervuilen met programmaspecifieke objecten.

Het is in puur VB inderdaad niet mogelijk om een plugin te maken zoals in C wel kan, punt. Je kan echter wel iets maken wat redelijk in de buurt komt. En de Compile Controller neemt inderdaad een groot deel van het RAD karakter van VB weg en de inline assembly ook, maar als je daarover valt, ben je waarschijnlijk toch niet in staat het te gebruiken.

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


Verwijderd

Korben schreef op 03 April 2003 @ 01:25:
[...]
Hier kun je heel veel redenen voor verzinnen. Eén van die redenen kan performance zijn. Alhoewel het zowiezo een slecht idee is om voor VB te gaan als je op performance hamert (nofi, het is zo), is wat jij beschrijft een interpreter binnen een interpreter. Als je P-code gebruikt. Maar zelfs dan, het is niet makkelijk om een snelle, effectieve interpreter te schrijven. En al helemaal niet met de technische onmogelijkheden die VB heeft. En zelfs al schrijf je de snelste interpreter ter wereld, dan nóg kan die met geen mogelijkheid op tegen geoptimaliseerde gecompileerde code. En ander probleem kan zijn dat er simpelweg geen tijd is om in feite een nieuwe scriptingtaal te verzinnen. Het probleem hier is dat je niet alleen te maken hebt met het schrijven van de logica om de taal te interpreteren, je moet ook nog eens de taal zelf verzinnen. En het lijkt zo makkelijk, maar je ziet heel makkelijk dingen over het hoofd. En er zijn gewoon dingen die, wederom door de technische limitaties van VB, niet efficiënt te implementeren zijn.
Klopt, alleen ik zei ook niet dat die plugin die je dan gebruikt niet gecompileerd hoeft te zijn.. je kunt natuurlijk ook gewoon een dll standaard aanroepen in je programma, en dus in je DLL de functies neerzetten die ervoor zorgen dat het juiste wordt weergegeven op je lcdtje.. als je dus een ander programma wilt, dan moet je ff een andere DLL reggen met dezelfde naam..

Verwijderd

precies, ik zit nu op school, maar ik kan als ik thuis ben wel eens wat code neerzetten en alles, ik gebruikte zelf gewoon een activex dll, en die kan je met wat api's registreren als dat nog niet is gedaan, dan zorg je dat elke plugin een class module heeft met dezelfde naam

dan via object = CreateObject(pluginnaam.MainModule) kan je het object creeeren, en heb je dus geen reference nodig. dit zou je iets moeten helpen.

Verwijderd

Mmm, ik zou de plugin idd willen opstellen als een ActiveX dll met een gedefinieerde interface. Op het moment dat je de plugin wil gebruiken doe je een CreateObject van de dll.

En over het gebruik van xml heb ik zo mijn vraagtekens want dat kan ook prima in een ini. Windows heeft al sinds versie 3 de getprivateprofile api-call om een ini uit te lezen.

In ieder geval zou ik de attributen van de vastleggen in een initialisatie bestand.

Verwijderd

zowiezo is het aan te raden om zoiets in C++ of C# te schrijven, maar als je het in VB doet kan het ook wel hoor.
Kben zelf bezig met C#, maar heb een tijd in VB6 geprogd, en je kunt er in principe alles mee, alleen IS het gewoon langzamer dan C(++/#).. das een feit, maar dat betekent dus niet dat het in VB niet KAN..
het kan perfect in VB, dus kloot gewoon ff lekker aan en je krijgt het echt wel werkend, en als je er niet meer uitkomt post het hier en dan zijn er zat mensen die je verder kunnen helpen.

/Edit/

Ini files gebruik ik niet meer, ik maak als ik data wil opslaan een .dat bestand aan, en daar sla ik de gegevens binair in op.

Simpelweg om gekloot van de gebruiker in dat soort bestanden te voorkomen..
/edit/

[ Voor 19% gewijzigd door Verwijderd op 03-04-2003 11:46 ]


  • Gerco
  • Registratie: Mei 2000
  • Laatst online: 18-08 22:57

Gerco

Professional Newbie

Verwijderd schreef op 03 April 2003 @ 11:45:
Simpelweg om gekloot van de gebruiker in dat soort bestanden te voorkomen..
/edit/
Mja, meestal zet ik dat soort dingen in de database (als er 1 is) en zet ik in mn config file alleen waar de database uithangt. Maar persoonlijk ben ik wel een groot voorstander van human read (en ook write)-able config files, gewoon omdat ze makkelijk zijn.

Als de gebruiker erin gaat kloten moet 'ie dat zelf weten, maar dan is het zn eigen verantwoordelijkheid als het gruwelijk misgaat.

- "Als ik zou willen dat je het begreep, legde ik het wel beter uit!" | All number systems are base 10!


  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
INI-files zijn (t.o.v. XML) echter niet hiërarchisch. Niet dat het met ini-files niet kan (en zeker in dit geval is een INI ook een goeie optie), maar ik ga liever voor XML. Zeker voor mijn settings e.d. Al is het maar met het oog op de toekomst, want die getprivateprofilestring API gaat vrees ik ook nog wel eens verdwijnen (eerder dan XML in ieder geval ;) ) En XML kan iedereen lezen ;)

Tevens kunnen (bij mijn weten) INI-files niet groter worden dan 64K (da's best veel, maar WEL een limitatie)

[ Voor 15% gewijzigd door RobIII op 03-04-2003 12:36 ]

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


Verwijderd

als je een binaire ini file schrijft en dus ook zelf de interpreter dan maakt het niks uit hoe groot je je ini file maakt.. dan kun je hem desnoods 4mb maken.. maare, heb jij wel es een ini file van 1mb of groter gezien dan?(readable text?)..

maargoed..
in een database kan inderdaad. das misschien wel een leuke om te onthouden.

  • RobIII
  • Registratie: December 2001
  • Niet online

RobIII

Admin Devschuur®

^ Romeinse Ⅲ ja!

(overleden)
maare, heb jij wel es een ini file van 1mb of groter gezien dan?
ik had het over 64K, da's dus 1/16e deel van 1Mb... Maar goed... ;)

There are only two hard problems in distributed systems: 2. Exactly-once delivery 1. Guaranteed order of messages 2. Exactly-once delivery.

Je eigen tweaker.me redirect

Over mij


  • DukeMan
  • Registratie: Mei 2000
  • Niet online
Er bestaan ook api's om op te vragen hoe de objectname van een DLL is. Hoef je al helemaal niets in een INI file vast te leggen. Heb ik ook gedaan en werkt erg goed.

Ik heb een functie ooit gemaakt die ik kon aanroepen met als parameter een pad naar een dll (c:\myapp\plugins\plugin1.dll).

Vervolgens ga ik in die functie via een api ophalen wat de objectname is, bijvoorbeeld MyPluginThatDoesThis. Standaard zorg ik ervoor dat mijn plugin een class heeft met de naar clsInterface. Vervolgens doe ik een createobject(MyPluginThatDoesThis.clsInterface), gaat dit fout, ga ik via een api de dll registreren. Als dit lukt, probeer ik nogmaals een createobject. Gaat dit goed, is de DLL een geldige plugin. Gaat dit fout, is de DLL geen geldige plugin.

Wat code
Visual Basic:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
Function LoadPlugin(strPath as string, strPluginFile as String)
    Dim objTLITypeLib As New TLI.TLIApplication
    Dim objTLIInfo As New TLI.TypeLibInfo

        'Get plugin object name and construct full name
        strPluginFile = strPath & strPluginFile
        
        'Create object to get plugin name with
        Set objTLITypeLib = New TLI.TLIApplication
        Set objTLIInfo = objTLITypeLib.TypeLibInfoFromFile(strPluginFile)
        
        'Get full objectname
        strObjectName = objTLIInfo.Name & ".FrameWork"
        
        'Check if object is a valid plugin
        If ValidatePlugin(strObjectName, strPluginFile) Then

          'Load plugin

        End If
End Function

Public Function ValidatePlugin(strObject As String, strPlugin As String) As Boolean

    Dim objPlugin As Object
    Dim strPluginCode As String
    Dim intErrorCode As Integer
    
    'Remove error handler
    On Error Resume Next
    
        'Try to create the object
        Set objPlugin = CreateObject(strObject)
        
        'Save error information
        intErrorCode = Err.Number
    
    'Set error handler
    On Error GoTo Err_Handler
    Err.Clear
    
    'Check if no error occured
    If intErrorCode = 429 Then
    
        'Try to register the object
        If RegisterComponent(strPlugin, DllRegisterServer) = [ActiveX Component Registered Successfully] Then
        
            'Remove error handler
            On Error Resume Next
            
                'Try to create the object
                Set objPlugin = CreateObject(strObject)
                
                'Save error information
                intErrorCode = Err.Number
            
            'Set error handler
            On Error GoTo Err_Handler
            Err.Clear
            
            'Check if no error occured
            If intErrorCode = 429 Then
            
                'An error occured, not a valid plugin
                ValidatePlugin = False
        
            Else
                
                'Plugin is valid
                ValidatePlugin = True
            
            End If
        
        Else
    
            'An error occured, not a valid plugin
            ValidatePlugin = False
        
        End If
        
    ElseIf intErrorCode <> 0 Then
    
        'An error occured, not a valid plugin
        ValidatePlugin = False
        
    Else
    
        'Get plugincode
        strPluginCode = objPlugin.GetPluginCode
        
        'Check plugincode
        If strPluginCode = g_strPluginCode Then
        
            'Plugin is valid
            ValidatePlugin = True
        
        Else
                    
            'Plugin is not valid
            ValidatePlugin = False
        End If
    
    End If
    
End Function


Ik denk dat je hier ook wel wat mee kan...
Pagina: 1