Toon posts:

[.NET] reflections

Pagina: 1
Acties:

Verwijderd

Topicstarter
Hallo allemaal, ik ben dus bezig met een Class te maken voor reflections, het is de bedoeling dat een assembly geladen kan worden in de class, waarna er wat simpele dingen gedaan kunnen worden met de assembly zoals het opvragen van de modules, functies, etc.. nu is er nog 1 stukje dat niet werkt, en dat is het aanroepen van de functie, ik gebruik:

Visual Basic:
1
2
3
4
5
6
7
8
    Public Function InvokeMethod(ByRef ModuleName As String, ByVal FunctionName As String, ByVal Params() As Object)

        Dim Method As MethodInfo
        Method = __modules(GetIndexByName(ModuleName)).GetMethod(FunctionName)

        Method.Invoke(__modules(GetIndexByName(ModuleName)), Params)

    End Function


de foutmelding die ik krijg is: Object does not match target type, als ik de functie GetHashCode probeer aan te roepen werkt het echter wel goed, is het de bedoeling dat elke propertie, functie in mijn assembly dan een object als return type heeft?

www.asp.net had ook geen artiekelen over reflections of iets, dus ja, ik heb even geen idee, zit nog steeds in msdn te bladeren, maar die gebruiken een binder, even kijken waar dat goed voor is.

Martin

nog ff toevoeging, __modules is een array met alle modules uit de Assembly, het resultaat van assembly.getTypes dus, GetIndexByName zoekt de index uit de array via de naam.

[ Voor 8% gewijzigd door Verwijderd op 17-07-2003 17:12 . Reden: stukje vergeten ]


  • EfBe
  • Registratie: Januari 2000
  • Niet online
Misschien kun je beter classes gaan maken dan modules. Classes zijn snel te laden en je kunt de methods meteen aanroepen, zonder Invoke crap.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • zneek
  • Registratie: Augustus 2001
  • Laatst online: 08-02-2025
EfBe schreef op 17 July 2003 @ 17:35:
Misschien kun je beter classes gaan maken dan modules. Classes zijn snel te laden en je kunt de methods meteen aanroepen, zonder Invoke crap.
Lol, heb je de startpost wel gelezen?

[edit] en nog eff ontopic: geen idee :)

[ Voor 8% gewijzigd door zneek op 17-07-2003 18:51 ]


  • EfBe
  • Registratie: Januari 2000
  • Niet online
zneek schreef op 17 juli 2003 @ 18:50:
[...]
Lol, heb je de startpost wel gelezen?
Ja sukkel, dat heb ik. Hij wil static methods in 'modules' aanroepen. Als je dat werkelijk wilt doen, is het natuurlijk jouw zaak, maar beter is modules te vergeten en met classes te werken. Je kunt dan veel gemakkelijker methods aanroepen van instances die je middels reflection instantieert.

TS: Het voorbeeld bij MethodBase.Invoke overloads is niet voldoende?

Ik denk overigens dat je params passed die niet overeenkomen met de methodheader van de method die je wilt aanroepen.

* EfBe , die graag ziet dat 'Modules' verdwijnt uit de native .NET api en verhuist naar de VB.NET only libraries.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 20-08 11:40

gorgi_19

Kruimeltjes zijn weer op :9

EfBe schreef op 17 July 2003 @ 19:16:
* EfBe , die graag ziet dat 'Modules' verdwijnt uit de native .NET api en verhuist naar de VB.NET only libraries.
offtopic:
Wat mij betreft hoeven ze die zut niet eens in VB.Net te laten, net zoals een hoop andere zooi zoals On Error Resume Next

@ TS:
Verder geldt heel sneaky dit dit een van de weinige keren is dat VB.Net case Sensitive is. Als je een method / namespace wil aanroepen, welke een verschil in case heeft, kan hij hem niet vinden.

[ Voor 4% gewijzigd door gorgi_19 op 17-07-2003 19:20 ]

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Verwijderd

Topicstarter
waarom hebben jullie het allemaal over modules, ik kan al mijn classes al zien in de assembly, ik kan alle functie argumenten opvragen, het enige wat ik nu nog wil doen is de functie aanroepen, dit werkt prima voor de GetHashCode functie, maar niet voor een andere functie die ik zelf in mijn class heb gedaan, zoals jullie weten heeft elke class de GetHashCode functie.

Dus de vraag is moet ik al mijn return types van het type object maken of niet? Dus ik heb allemaal classes, en het is voor een plugin framework, dus ik neem aan dat dit de enige manier is.

Martin

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Je bent niet duidelijk, Wootz: wil je een functie in een VB.NET module aanroepen of wil je een class method aanroepen? In het 1e geval, praat je dus over modules, in het 2e geval is het dus handiger een CreateInstance call te doen op de assembly en dan de method aan te roepen, typed dus.

[edit]
Een plugin network is makkelijker gebouwd wanneer je iedere plugin een interface laat implementeren. Dan kun je doen:

Java:
1
2
3
4
5
Assembly myPluginAssembly = Assembly.Load("lalala.dll");

IMyPluginInterface plugin = myPluginAssembly.CreateInstance("PluginClassToInstantiate");

plugin.KnownMethod();

[ Voor 37% gewijzigd door EfBe op 17-07-2003 20:33 ]

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Verwijderd

Topicstarter
mhmm, dat is dus ook een manier, ik dacht dat ik het gewoon via de MethodInfo class kon doen, maar ja, dit is de manier die ik ook in VB6 deed, zoals je ziet gebruikte ik de GetTypes functie, oftewel krijg ik dus de classes, maar dit gaat wel werken.

bedankt,
Martin

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Verwijderd schreef op 17 July 2003 @ 22:20:
mhmm, dat is dus ook een manier, ik dacht dat ik het gewoon via de MethodInfo class kon doen, maar ja, dit is de manier die ik ook in VB6 deed, zoals je ziet gebruikte ik de GetTypes functie, oftewel krijg ik dus de classes, maar dit gaat wel werken.
Ik gebruik het zelf ook, vandaar dat ik het ook suggereerde als mogelijke optie :) Je kunt ook je plugins zo vanuit je programma debuggen overigens, copieer dan de .pdb file bij je dll (debug build) en wanneer je in de method stept, step je dus in je plugin code.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


  • zneek
  • Registratie: Augustus 2001
  • Laatst online: 08-02-2025
EfBe schreef op 17 July 2003 @ 19:16:
[...]

Ja sukkel, dat heb ik. Hij wil static methods in 'modules' aanroepen. Als je dat werkelijk wilt doen, is het natuurlijk jouw zaak, maar beter is modules te vergeten en met classes te werken.
Lalala 8)7 Ik moe me bek ook houden over onderwerpen waar ik niet in zit :) soz.

[ Voor 3% gewijzigd door zneek op 17-07-2003 23:49 ]


  • Ramon
  • Registratie: Juli 2000
  • Laatst online: 23:00
afgezien daarvan vind ik het niet kunnen dat we hier elkaar voor sukkel gaan lopen uitschelden....

Check mijn V&A ads: https://tweakers.net/aanbod/user/9258/


Verwijderd

Topicstarter
Ok nog even een korte vraag, ik moet dus alleen nog een interface opnemen in mijn hoofdprogramma, moeten de plugins die ook werkelijke gebruiken? Of als de functienamen hetzelfde zijn is het dan al goed?

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Verwijderd schreef op 18 juli 2003 @ 10:07:
Ok nog even een korte vraag, ik moet dus alleen nog een interface opnemen in mijn hoofdprogramma, moeten de plugins die ook werkelijke gebruiken? Of als de functienamen hetzelfde zijn is het dan al goed?
Het beste wat je kunt doen is een apart project maken met daarin alleen je interface. Dat compileert naar een aparte DLL. Die DLL en dus die interface moet je als reference opnemen in zowel je eigen programma als in de plugin projects. Zo heb je in beide projects de interface. Nu moeten alle plugins de interface implementeren. Zodoende kun je alle mogelijke classes uniform benaderen: middels de interface.

Plugins moeten sowieso altijd een uniforme interface hebben, immers, hoe kan de host anders een functie aanroepen als de host niet weet welke functie hij moet aanroepen ten tijde dat de host wordt gecompileerd?

Interfaces zijn een must bij late-binding software, ik zou zeker de documentatie over Interfaces in VB.NET doornemen. In VB5/6 waren ze niet interessant, maar in .NET wel degelijk :)

Verder, wanneer je bv meerdere typen plugins wilt ondersteunen kun je een hierarchie van interfaces definieren, bv: (C#, maar VB.NET werkt hetzelfde)

public interface IFoo
{
...
}

public interface IBar : IFoo
{
...
}

Nu kun je dus classes hebben die IFoo implementeren en classes die IBar implementeren. Je kunt testen (in C# met het statement 'is' geen idee wat het VB.NET statement is) of een object van een bepaald type is, bv wanneer je eerst middels IFoo een instance hebt gecreeerd en je wilt weten of dit een IBar plugin is. Als dat zo is kun je casten naar IBar (Middels CType). Je kunt dit ook doen middels een property die een Enum teruggeeft wat het type aangeeft, maar dit is minder uitbreidbaar.

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Verwijderd

Topicstarter
ok nog even een vraag, ik heb dus nu het volgende

Visual Basic:
1
2
3
        Dim myInterface As DLC.Interfaces.pFixture

        myInterface = __assembly.CreateInstance(GetIndexByName(ModuleName))


ik moet alleen nog ff de variable ModuleName gaan veranderen in ClassName, maar dat stuk werkt nu, ik heb de interface gemaakt en in een nieuwe assembly gestopt, nu is dus de vraag, ik heb een algemene functie gemaakt die een functie moet aanroepen (wat ik dus eerst via Invoke wou doen) kan ik dynamisch een functie aanroepen? Ik geef dus een variable functionname mee

iets van eval('myInterface.' + functionname) in JS, kan dit ook onder .NET of moet ik voor elke functie een functie in mijn host maken?

Martin

  • EfBe
  • Registratie: Januari 2000
  • Niet online
Hoe kan een plugin systeem nu werken wanneer de host de functies niet kent in de plugins?

Je moet je plugin interface zo maken (en prefix ze met 'I', dan weet je dat het een interface is :)) dat deze 1 of 2 methods heeft bv 'DoWork()' en bv DoWorkSpecial() en dat je daaraan meegeeft alle objects met data die eventueel voor een plugin van belang kunnen en mogen zijn. De plugin zoekt het verder dan maar uit.

Plugins in bv photoshop or Cubase werken allemaal op dezelfde manier: ze implementeren een bekende interface en daardoor kan de host ze aanroepen. Hoe de plugin dan werkt en wat deze doet is voor de host niet van belang. De plugin kan best extra methods hebben die bekend zijn bij classes die door andere plugins worden aangeroepen, maar dat gaat dan buiten de host om. Snap je een beetje wat ik bedoel? Of is jouw plugin network iets wat altijd alle mogelijke methods moet kunnen aanroepen met alle mogelijke data? (wat op zich al onmogelijk is vanuit een statisch gecompileerd programma)

Creator of: LLBLGen Pro | Camera mods for games
Photography portfolio: https://fransbouma.com


Verwijderd

Topicstarter
okay, dat heb ik al, ik heb een algemene doFunction met een params array, en voor de rest kiest de plugin dan wat die moet doen, vroeg het me alleen af, maakt niet zoveel uit, nu moet ik alleen ff alle functies mappen. Maar ik had onder vb6 al zoiets eens gedaan met dynamische functies.

ik ga het ff proberen.

Verwijderd

Topicstarter
ok, probleem weer, ik probeer dus mijn code nu uit, en het werkt niet

Visual Basic:
1
2
3
4
5
6
7
    Public Function GetFixtureName() As String

        Dim myInterface As dlc.interfaces.IFixture = __assembly.CreateInstance("cMain")

        Return myInterface.FixtureName

    End Function


myInterface blijft nothing, oftewel leeg, cMain is wel de naam van de class. Ik heb nu even geen ideeen meer, ander probleem dat ik heb is dat ik nu dus die dll heb met mijn interface er in, die staat in de bin dir van mijn host, maar de plugins staan onder AppData/fixtures dus heb ik ook daar maar even een kopie neergezet van de interface dll, kan ik dit op een andere manier oplossen? moet ik het dan in de GAC kopieren?

Martin

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 20-08 11:40

gorgi_19

Kruimeltjes zijn weer op :9

Je moet het inclusief namespace doen.

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Verwijderd

Topicstarter
woo, het werkt eindelijk bedankt, toch best vreemd, in het eerste geval had ik het namelijk helemaal zonder namespace gedaan, maar was denk ik toch niet zo'n goede oplossing, dus nu met namespace, maar elke plugin heeft dezelfde namespace dadelijk dlc.fixtures kunnen dan alle plugins nog steeds dezelfde cMain class bevatten?

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 20-08 11:40

gorgi_19

Kruimeltjes zijn weer op :9

dlc.fixtures.cMain mag maar 1 keer voorkomen.

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Verwijderd

Topicstarter
per assembly? maar ik maak meerdere plugins, verschillende assemblies dus, mag het dan wel? omdat ik dan assembly.loadfrom gebruikt, zal hij die maar 1 keer tegen komen. Maar als ik het in de GAC ga doen moeten ze wel uniek worden?

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 20-08 11:40

gorgi_19

Kruimeltjes zijn weer op :9

Verwijderd schreef op 18 July 2003 @ 14:27:
per assembly? maar ik maak meerdere plugins, verschillende assemblies dus, mag het dan wel? omdat ik dan assembly.loadfrom gebruikt, zal hij die maar 1 keer tegen komen. Maar als ik het in de GAC ga doen moeten ze wel uniek worden?
Probeer het uit.. Maak een assembly, kopieer deze en zet deze vervolgens in dezelfde bin-directory. Ik weet bijna zeker dat je dan een fout krijgt. De namespace mag in verschillende assembly's voorkomen; een class icm assembly moet, afaik, uniek zijn. (en dit is niet gebonden per assembly, maar per alle assembly's)

[ Voor 16% gewijzigd door gorgi_19 op 18-07-2003 14:28 ]

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Verwijderd

Topicstarter
okay ik ga het zo proberen, maar de ene assembly weet toch niks van de ander als ik het via reflection doe? Is zo maar even uit mijn hoofd, ik ga het straks even uitproberen, eerst mijn class een beetje opruimen, is een beetje een zooitje geworden. Dan eens kijken in hardware i/o, zal wel met C++.NET worden

  • gorgi_19
  • Registratie: Mei 2002
  • Laatst online: 20-08 11:40

gorgi_19

Kruimeltjes zijn weer op :9

Verwijderd schreef op 18 juli 2003 @ 14:30:
okay ik ga het zo proberen, maar de ene assembly weet toch niks van de ander als ik het via reflection doe? Is zo maar even uit mijn hoofd, ik ga het straks even uitproberen, eerst mijn class een beetje opruimen, is een beetje een zooitje geworden. Dan eens kijken in hardware i/o, zal wel met C++.NET worden
Nope, maar afaik worden ze allemaal wel geladen. Maar je kan het allicht uitproberen. Andere optie is dat een assembly geregistreerd moet worden; zo voorkom je ook dat probleem.

* gorgi_19 heeft het destijds opgelost door een apart configuratiebestand te maken met daarin de namespaces, assemblynamen en de aanroepcodes.

[ Voor 11% gewijzigd door gorgi_19 op 18-07-2003 14:32 ]

Digitaal onderwijsmateriaal, leermateriaal voor hbo


Verwijderd

Topicstarter
dat is ook nog een optie, maar je kan natuurlijk ook via reflection gewoon de namespace opvragen en dan een string samenstellen die de call gaat vormen dus class.namespace + "cMain" zou ook moeten werken.
Pagina: 1