2010-03-12 4 views
4

Je suis en train d'écrire un wrapper C# pour la lumière API commune Dallmeier (Camera & Surviellance systems) et je n'ai jamais écrit de wrapper auparavant, mais j'ai utilisé le wrapper Canon EDSDK C#. J'utilise donc l'emballage de Canon comme guide pour écrire l'emballage de Dallmeier.Enveloppe C# et rappels

Je rencontre actuellement des problèmes avec l'appel d'un rappel. Dans le manuel de l'API, il a les éléments suivants:

dlm_connect

int(unsigned long uLWindowHandle, 
    const char * strIP, 
    const char* strUser1, 
    const char* strPwd1, 
    const char* strUser2, 
    const char* strPwd2, 
    void (*callback)(void *pParameters, void *pResult, void *pInput), 
    void * pInput) 

Arguments
- ulWindowhandle - poignée de la fenêtre qui est passé à la ViewerSDK pour afficher la vidéo et les messages là-bas
- strUser1/2 - noms des utilisateurs à se connecter. Si une seule connexion utilisateur unique est utilisée strUser2 est
- NULL
- strPwd1/2 - mots de passe des deux utilisateurs. Si strUser2 est NULL, strPwd2 est ignoré.

Retour
Cette fonction crée un SessionHandle qui doit être passé

Callback
pParameters seront structurés:
- unsigned long ulFunctionID
- unsigned long ulSocketHandle, // à gérer socket de la connexion établie
- unsigned long ulWindowHandle,
- int SessionHandle, // poignée de session de la session créée
- const char * Dénudez,
- const char * strUser1,
- const char * strPwd1,
- const char * strUser2,
- const char * strPWD2
pResult est un pointeur vers un entier représentant le résultat de l'opération. Zéro sur le succès. Les valeurs négatives sont des codes d'erreur. Donc, d'après ce que j'ai lu sur le Net et Stack Overflow - C# utilise des délégués pour les rappels. Je crée donc une ma fonction de rappel:

public delegate uint DallmeierCallback(DallPparameters pParameters, IntPtr pResult, IntPtr pInput); 

Je crée la fonction de connexion

[DllImport("davidapidis.dll")] 
public extern static int dlm_connect(int ulWindowHandle, string strIP, string strUser1, string strPwd1, string strUser2, string strPwd2, DallmeierCallback inDallmeierFunc 

Et (je pense) les DallPParameters comme struct:

[StructLayout(LayoutKind.Sequential)] 
public struct DallPParameters 
{ 
    public int ulfunctionID; 
    public int ulsocketHandle; 
    public int ulWindowHandle; 
    ... 
} 

Tout cela est en ma classe d'emballage.
Suis-je dans la bonne direction ou est-ce complètement faux?
Puis dans ma classe Dallmeier je les suivantes:

private DallmeierAPI dallmeierAPI; 
    private DallmeierSDK.DallmeierCallback dallCallbackHandler; 
    private GCHandle handle; 
    private IntPtr pResult; 
    private IntPtr pInput; 

    internal Dallmeier() 
    { 
     this.dallmeierAPI = DallmeierAPI.Instance; 

     registerEvents(); 
    } 

    private void registerEvents() 
    { 
     // Register Callback Events 
     dallCallbackHandler = new DallmeierSDK.DallmeierCallback(pParameters, pResult, pInput); // Error: Method Name expected 

     handle = GCHandle.Alloc(dallCallbackHandler); 
    } 

    private void unregisterEvents() 
    { 
     handle.Free(); 
    } 

    private DallmeierSDK.DallPParameters pParameters(int ulfunctionID, int ulSocketHandl, int ulWindowHandle, int SessionHandle, string strIP, string strUser1, string strPwd1, string strUser2, string strPwd) 
    { 
     // what goes in here : Error not all code paths return a value 
    } 


} 

Alors, quand j'enregistrer le rappel de son dire un Nom de la méthode devrait?
et pParameters attend une valeur de retour?

+0

Votre méthode de rappel doit correspondre à la signature du type de délégué. Vous écrivez alors 'new DallmeierSDK.DallmeierCallback (SomeMethodName)'. – SLaks

+0

Merci SLaks. J'ai eu ce travail. – fergs

Répondre

2

Vous êtes pour la plupart sur la bonne voie.

Cependant, C long s sont (je crois) 32 bits, et correspondent à C# int s.
De même, après avoir appelé la fonction, vous devez conserver une référence managée à l'instance déléguée que vous avez transmise pour vous assurer que le délégué ne récupère pas la mémoire.

+1

+1 pour mentionner la référence. J'ai oublié de garder une référence au délégué une fois ... c'était amusant. :) – Tanzelax

+0

merci pour la réponse rapide. J'ai fait une modification sur le poste et changé les longs en ints. Est-ce que j'utilise - GCHandle.Alloc - pour garder une référence managée? – fergs

+0

Ou juste faire un champ dans votre classe (en supposant que la classe durera assez longtemps) – SLaks