IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Framework .NET Discussion :

problème avec un appel de fonction de callback de C++ vers C#


Sujet :

Framework .NET

  1. #1
    Nouveau candidat au Club
    Inscrit en
    Janvier 2007
    Messages
    1
    Détails du profil
    Informations forums :
    Inscription : Janvier 2007
    Messages : 1
    Par défaut problème avec un appel de fonction de callback de C++ vers C#
    Bonjour,

    Mon problème est le suivant :
    - J'ai une DLL en C++ qui est appelée par une application en C#, un pointeur de fonction sur une callback est passé lors de cet appel (ceci afin de pouvoir gérer une fonction de progress dans l'application en C#).
    - Il semble que tout soit OK, seulement lors de l'appel de la fonction de callback par la DLL, une erreur est générée.

    Il semblerait que le prototype de la fonction de callback soit faux, dans l'appli en C#, voici la partie de source code incriminée :

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    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
    {
    // callback prototype
    public unsafe delegate int PROGRESSCALLBACK( int reader, void* pUserData, int progress, int status );
    // C++ DLL function called
    [DllImport( "ePerso.dll" )] public static extern unsafe int ePersoRead( int iReader, int iBlock, [MarshalAs( UnmanagedType.FunctionPtr )] PROGRESSCALLBACK pFnCallBack, void* pUserData, ref int piSize, char* pDG );
     
    //callback function
    private int ReadProgress( int reader, void * pUserData, int progress, int status )
    {
    try
    {
    if ( reader == READER1 ) SetStatusRead( reader, ref toolStripStatusLabelReader1, progress, status );
    if ( reader == READER2 ) SetStatusRead( reader, ref toolStripStatusLabelReader2, progress, status );
    if ( reader == READER3 ) SetStatusRead( reader, ref toolStripStatusLabelReader3, progress, status );
    if ( reader == READER4 ) SetStatusRead( reader, ref toolStripStatusLabelReader4, progress, status );
    }
    catch ( Exception ex )
    {
    MessageBox.Show( ex.Message.ToString() );
    }
     
    return 0;
    }
     
    // function which is calling the C++ DLL
    unsafe private void Read( int reader, string MRZ, ref PassportReader PPReader, ref ToolStripStatusLabel ctl)
    {
    try
    {
    ctl.Text = "";
    if ( mb_Connected == true )
    {
    int status;
    if ( ( status = ePersoReset( reader ) ) == 0 )
    {
    if ( ( status = ePersoSetBACKeys( reader, MRZ.ToCharArray() ) ) != 0 )
    ctl.Text = "Failed to set BAC keys : " + status.ToString();
     
    if ( status == 0 )
    {
    PPReader.State = READ_START;
    if ( reader == READER1 ) ProcessRead(reader, ref PPReader, ref toolStripStatusLabelReader1, ref mi_SizeReader1 );
    if ( reader == READER2 ) ProcessRead(reader, ref PPReader, ref toolStripStatusLabelReader2, ref mi_SizeReader2 );
    if ( reader == READER3 ) ProcessRead(reader, ref PPReader, ref toolStripStatusLabelReader3, ref mi_SizeReader3 );
    if ( reader == READER4 ) ProcessRead(reader, ref PPReader, ref toolStripStatusLabelReader4, ref mi_SizeReader4 );
    }
    }
    }
    else
    {
    ctl.Text = "Not Connected !";
    }
    }
    catch ( Exception ex )
    {
    MessageBox.Show( ex.Message.ToString() );
    }
    }
     
    private unsafe void ProcessRead(int reader, ref PassportReader PPReader, ref ToolStripStatusLabel ctl, ref int size )
            {
                int status;
     
                switch ( PPReader.State )
                {
                    case READ_START:
                        // Get the EF.COM size
                        PPReader.State = READ_EFCOM_SIZE;
     
                        // Get the current CPU time
                        PPReader.Start = DateTime.Now;
     
                        // Read EF com size
                        if ( ( status = ePersoRead( reader, 0, new PROGRESSCALLBACK( this.ReadProgress ), null, ref size, null ) ) != 0 )
                            ctl.Text = "Read EF.COM size failed : " + status.ToString();
     
                        break;
     
                    case READ_EFCOM_SIZE:
     
                        // Get the EF.COM data
                        PPReader.State = READ_EFCOM;
     
                        // Allocate space for data
                        PPReader.DG0 = new char[size];
                        fixed ( char* sTmp = PPReader.DG0 )
                        { 
                            // Read EF com
                            if ( ( status = ePersoRead( reader, 0, new PROGRESSCALLBACK(this.ReadProgress), null, ref size, sTmp ) ) != 0 )
                                ctl.Text = "Read EF.COM data failed : " + status.ToString();
                        }
                        break;
     
                    case READ_EFCOM:
     
     
                        break;
                }
     
            }

    J'ai essayé de définir le type "void *" en type "[MarshalAs( UnmanagedType.AsAny )] Object", mais on ne peut pas définir le type "void *" de cette manière dans le prototype de la fonction de callback.

    J'ai essayé de conserver la référence de l'instance de mon délégué, mais cela n'a rien changé, j'ai toujours la même erreur :

    "The value of ESP was not properly saved accross a function call. This usually a result of calling a function declared with one calling convention with a function pointer declared with a different calling convention."


    Voici le prototype de ma fonction de callback en C++:

    Code c++ : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    typedef long (*PROGRESSCALLBACK)(long reader, void * pUserData, long progress, long status);

    Peut-être que mon prototype de fonction de callback en C# est faus, mais je ne vois pas où, le voici à titre d'information:

    Code c# : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    public unsafe delegate int PROGRESSCALLBACK( int reader, void* pUserData, int progress, int status );

    Quelqu'un a-t-il la solution a mon problème (qui soit dit en passant commence à me rendre chèvre).

    Merci d'avance à celles ou ceux qui pourront trouver une solution à ce problème (je ferai une publication sur le site MSDN et elles seront bien sur citées).

    @+

  2. #2
    Membre éclairé
    Profil pro
    Inscrit en
    Avril 2006
    Messages
    349
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Ille et Vilaine (Bretagne)

    Informations forums :
    Inscription : Avril 2006
    Messages : 349
    Par défaut
    Salut !

    Ton message d'erreur parle de problème de convention d'appel, essaye de la préciser lors de ton DllImport.

    ++

Discussions similaires

  1. [DOM XML] Problème avec l'une des fonctions
    Par Joe Le Mort dans le forum Bibliothèques et frameworks
    Réponses: 2
    Dernier message: 08/11/2006, 15h20
  2. Problème avec la signature des fonctions dll
    Par mdefo dans le forum MATLAB
    Réponses: 1
    Dernier message: 20/09/2006, 14h23
  3. problème avec l'appel d'une fonction
    Par mademoizel dans le forum ASP
    Réponses: 5
    Dernier message: 26/06/2006, 15h04
  4. [PL SQL] Problème avec 'case' dans une fonction
    Par divail dans le forum Oracle
    Réponses: 14
    Dernier message: 13/03/2006, 15h50
  5. Réponses: 6
    Dernier message: 20/01/2006, 19h28

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo