don_Vito Skrevet 15. februar 2007 Del Skrevet 15. februar 2007 Hei.. Jeg bruker en dll som er lagd i vc++. Denne har et par callback-funksjoner som jeg ikke helt får taket på. extern "C" { void WINAPI RRCallback(void (WINAPI *f)(int, BSTR buffer, int)); void WINAPI RDCallback(void (WINAPI *f)(void)); ... } } dette gjør jeg: Private Declare Sub RRCallback Lib "nn.dll" (ByVal callback As RRCallbackCB)) Private Declare Sub RDCallback Lib "nn.dll" (ByVal callback As RDCallbackCB) og: Public Delegate Sub RRCallbackCB(ByVal Cmd As Integer, ByVal Buffer As String, ByVal seq As Integer) Public Delegate Sub RDCallbackCB() RRCallback(AddressOf ReceiveCallback) RDCallback(AddressOf ServerConDropped) Sub ReceiveCallback(ByVal Cmd As Integer, ByVal Buffer As String, ByVal seq As Integer) Public Sub DisconnectServer() Vet ikke om det er så godt å forstå dette men.. Hva gjør jeg feil her? Lenke til kommentar
GeirGrusom Skrevet 15. februar 2007 Del Skrevet 15. februar 2007 Egentlig kan jeg ikke se noe galt... Hva skjer når du starter programmet? Lenke til kommentar
don_Vito Skrevet 15. februar 2007 Forfatter Del Skrevet 15. februar 2007 Får ikke noe melding om at dette er feil. Men jeg får ikke noe data ut fra dll'en. Så jeg lurte derfor på om jeg har skrevet dette feil. Lenke til kommentar
GeirGrusom Skrevet 15. februar 2007 Del Skrevet 15. februar 2007 Men kommer den til Callback funksjonene? Det er mulig du må legge til <System.Runtime.InteropServices.MarshalAs( System.Runtime.InteropServices.UnmanagedType.FunctionPtr)> attributen før hver av callback parameterne. Lenke til kommentar
don_Vito Skrevet 15. februar 2007 Forfatter Del Skrevet 15. februar 2007 Jo den kommer til callback funksjonene,, mener du at jeg skal skrive dette: Private Declare Sub RRCallback Lib "nn.dll" (<System.Runtime.InteropServices.MarshalAs( System.Runtime.InteropServices.UnmanagedType.FunctionPtr)>ByVal callback As RRCallbackCB) ? Lenke til kommentar
GeirGrusom Skrevet 15. februar 2007 Del Skrevet 15. februar 2007 Ja, men det er ikke nødvendig hvis callback funksjonene fungerer. Jeg forstår ikke hva som er i veien, hvis det fungerer :/ Lenke til kommentar
don_Vito Skrevet 21. februar 2007 Forfatter Del Skrevet 21. februar 2007 Denne feilmeldingen får jeg nå: A callback was made on a garbage collected delegate of type 'blablabla+RDCallbackCB::Invoke'. This may cause application crashes, corruption and data loss. When passing delegates to unmanaged code, they must be kept alive by the managed application until it is guaranteed that they will never be called. Hvordan unngår jeg dette? Lenke til kommentar
wolf5 Skrevet 21. februar 2007 Del Skrevet 21. februar 2007 Ved å unngå at garbage collectorn interesserer seg for objektene dine. Behold en eller annen referanse til dem eller evt gjør dem static. Garbage collector tar seg av alt som koden din ikke lengre benytter seg av. Den vet desverre ikke at den eksterne DLL'en din har en referanse til callback funksjonen. Så ved å enten gjøre ting static eller beholde en referanse en eller annen plass til klassen til callback funksjonen eller gjøre funksjonen static så tror jeg du skal unngå den der. Lenke til kommentar
GeirGrusom Skrevet 21. februar 2007 Del Skrevet 21. februar 2007 For å tvinge frem dette, kan du bruke System.Runtime.Interop.GCHandle strukturen. Pass på at denne ikke faller ut av scope før du har kalt Free! Lenke til kommentar
don_Vito Skrevet 23. februar 2007 Forfatter Del Skrevet 23. februar 2007 javel.. Hvordan gjør jeg det da? Lenke til kommentar
GeirGrusom Skrevet 23. februar 2007 Del Skrevet 23. februar 2007 (endret) Poenget er at objektet som eier callback funksjonenm må ikke bli slettet fra minnet. Bare pass på at den ikke forsvinner ut av scope: int main() { { MyCallBackClass cl = new MyCallBacklClass(); NativeFunctions.AssigneDelegate(cl.SomeFunction) } NativeFunctions.CallDelegate(); // ÆRRÅR: cl har forsvunnet "out of scope" } Den beste løsningen: int main() { MyCallBackClass cl = new MyCallBacklClass(); { NativeFunctions.AssigneDelegate(cl.SomeFunction) } NativeFunctions.CallDelegate(); // Success! Den mindre beste løsningen: int main() { System.Runtime.Interop.GCHandle handle; { MyCallBackClass cl = new MyCallBacklClass(); handle = Systenm.Interop.GCHandle.Alloc(cl, Pinned); NativeFunctions.AssigneDelegate(cl.SomeFunction) } NativeFunctions.CallDelegate(); // Success! handle.Free(); edit:Forresten, har du husket å deklarere funksjonene static? Endret 23. februar 2007 av GeirGrusom Lenke til kommentar
don_Vito Skrevet 28. februar 2007 Forfatter Del Skrevet 28. februar 2007 (endret) edit:Forresten, har du husket å deklarere funksjonene static? 8007609[/snapback] Hvilke funksjoner da? Sånn du mener? Static Dim c As New RRCB(AddressOf cdll.ReceiveCallback) Static Dim cc As New RDCB(AddressOf cdll.ServerConDropped) Endret 28. februar 2007 av don_Vito Lenke til kommentar
GeirGrusom Skrevet 28. februar 2007 Del Skrevet 28. februar 2007 (endret) Er ikke sikker på om det heter shared, eller static i VB.NET... en av dem Grunnen er at da trenger du ikke noen referanser, som eliminerer feilen helt. cdll.ReceiveCallback og den andre må være deklarert Shared eller Static Endret 28. februar 2007 av GeirGrusom Lenke til kommentar
don_Vito Skrevet 12. mars 2007 Forfatter Del Skrevet 12. mars 2007 Da har dette løst seg ved å deklarere de nødvendige funksjonene som shared. + at jeg måtte gjøre dette for å få BSTR til å funke: <System.Runtime.InteropServices.MarshalAs(System.Runtime.InteropServices.UnmanagedType.BStr)> ByVal Buffer As String Buffer er en BSTR i API'et. Men nå har jeg et nytt spørsmål. Denne .dll blir brukt som tilkobling mot en server (proprietært). Dll'en kan håndtere en tilkobling av gangen, men jeg ønsker å kunne ha flere tilkoblinger til denne serveren (en multithreaded klient). Har dere noe forslag på hvordan jeg kan løse dette? Kan klienten ha flere "sessions" mot denne dll'en? Lenke til kommentar
GeirGrusom Skrevet 12. mars 2007 Del Skrevet 12. mars 2007 (endret) Ja, tror du kan få til dette med Appdomain edit: eller kanskje det går automatisk med flere threads? Endret 13. mars 2007 av GeirGrusom Lenke til kommentar
Anbefalte innlegg
Opprett en konto eller logg inn for å kommentere
Du må være et medlem for å kunne skrive en kommentar
Opprett konto
Det er enkelt å melde seg inn for å starte en ny konto!
Start en kontoLogg inn
Har du allerede en konto? Logg inn her.
Logg inn nå