Gå til innhold

Callback-funksjoner i VB2005


Anbefalte innlegg

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
Videoannonse
Annonse

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

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

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

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 av GeirGrusom
Lenke til kommentar
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 av don_Vito
Lenke til kommentar
  • 2 uker senere...

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

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 konto

Logg inn

Har du allerede en konto? Logg inn her.

Logg inn nå
×
×
  • Opprett ny...