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

C# Discussion :

P/Invoke de C à C#


Sujet :

C#

  1. #1
    Membre averti
    Inscrit en
    Février 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 13
    Par défaut P/Invoke de C à C#
    Bonjour à tous j'essaye inlassablement d'utiliser ma DLL écrit en C, mais sans vain.

    Voici ma signature :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    DLL_INTER_Nouvelle_Evaluation(int ** tab_point,int nbpoint);

    J'ai essayé de marshaller l'int ** par ref Int tab_point,
    il m'affiche :
    Tentative de lecture ou d'écriture de mémoire protégée. Cela indique souvent qu'une autre mémoire est endommagée.
    je suis à court d'idée si quelqu'un a une idée lumineuse je suis preneur.

    Merci.

  2. #2
    Membre chevronné
    Homme Profil pro
    Développeur informatique
    Inscrit en
    Décembre 2005
    Messages
    482
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 44

    Informations professionnelles :
    Activité : Développeur informatique
    Secteur : Agroalimentaire - Agriculture

    Informations forums :
    Inscription : Décembre 2005
    Messages : 482
    Par défaut
    salut,
    essaye de cocher "Autoriser du code unsafe" dans les
    propriétés de ton projet / Générer

    sinon ze sais po
    et sinon essaye avec du vain

  3. #3
    Membre averti
    Inscrit en
    Février 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 13
    Par défaut
    Unsafe? quelle est la fonction de l'unsafe ?

  4. #4
    Membre averti
    Inscrit en
    Février 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 13
    Par défaut
    Voila ce que j'ai fait :

    Code : 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
    public static unsafe extern void DLL_INTER_Nouvelle_Evaluation(int ** monTab, int nbpoint);
     
        unsafe
        {
         int** tab_point;
         int nbpoint;
     
         //Initialisation
         nbpoint = 3;
         tab_point = (int**)Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Int32)));
     
         for (int i = 0; i < 2; i++)
         {
          tab_point[i] = (int*)Marshal.AllocHGlobal(Marshal.SizeOf(typeof(Int32)));
         }
     
         tab_point[0][0] = 2;
         tab_point[1][0] = 2;
         tab_point[0][1] = 5;
         tab_point[1][1] = 2;
         tab_point[0][2] = 7;
         tab_point[1][2] = 2;
         tab_point[0][3] = 52;
         tab_point[3][2] = 36;
         Console.WriteLine(tab_point[1][0]);
         Console.WriteLine(tab_point[1][2]);
     
         DLL_INTER_Nouvelle_Evaluation(tab_point, nbpoint);
         Console.WriteLine("Nouvelle Evaluation OK");
       }
    mais j'arrive à accéeder à la 3eme indice alors que je l'ai définit que jusqu'à 2
    pourriez vous m'aider plz.

  5. #5
    Membre éprouvé
    Profil pro
    Inscrit en
    Novembre 2007
    Messages
    99
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Novembre 2007
    Messages : 99
    Par défaut
    int** != ref int mais int* => du coup, ça me paraissait trivial mais j'ai voulu faire un test juste pour trouver le plus simple et le plus rapide : c'est plus compliqué que je ne pensais et ça me prend la tête !

    Une seule fonction dans ma dll
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
     
    void __stdcall Clear(int** ptrptrArray, int len)
    {
         int* ptrArray = *ptrptrArray;
         while( len-- )
              *(ptrArray + len) = 0;
    }
    Cette déclaration, la plus simple, la plus naturelle ne fonctionne pas ! La fonction récupère les bon args mais au retour le tableau a perdu ses dimensions. J'ai essayé sans utiliser MarshalAs => pas de solution.
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    // Au retour le tableau est niqué pourtant c'est correct.
    static extern void Clear(ref int[,] tableau, int dimension);
    Ces 2 autres déclarations fonctionnent, appellent la même fonction, mais c'est super lourd (en même temps c'est du c#...)
    Code : 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
     
    [DllImport("DevTest.dll")]
    static extern void Clear([MarshalAs(UnmanagedType.LPArray, SizeParamIndex = 1)]ref int[] tableau, int dimension);
     
    [DllImport("DevTest.dll")]
    static extern void Clear(ref IntPtr tableau, int dimension);
     
    // Uni
    int[] uni = { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };
    foreach (int i in uni)
         Console.WriteLine(i);
     
     
    Clear(ref uni, uni.Length);
    foreach (int i in uni)
         Console.WriteLine(i);
     
    // Mutli
    int[,] multi = {
                    {0,1},
                    {2,3},
                    {4,5},
                    {6,7},
                    {8,9},
               };
     
    // Ca c'est juste pour compliquer
    for (int i = 0; i <= multi.GetUpperBound(0); i++)
    {
         for (int j = 0; j <= multi.GetUpperBound(1); j++)
              Console.WriteLine(multi[i, j]);
    }
     
    // Ca c'est pour essayer
    unsafe
    {
         fixed (int* ptr = multi)
         {
              // ICI C'EST POUR UTILISER LA MEME FONCTION
              IntPtr ptrptr = new IntPtr(ptr);
     
              Clear(ref ptrptr, multi.Length);
         }
    }
     
    foreach (int i in multi)
         Console.WriteLine(i);

  6. #6
    Membre averti
    Inscrit en
    Février 2009
    Messages
    13
    Détails du profil
    Informations forums :
    Inscription : Février 2009
    Messages : 13
    Par défaut Merci
    Merci de t'avoir prie la tête, ça marche le truc c'est qu'on utilise de l'unsafe :-(.
    Mais bon je suis preneur de la solution.

    Par contre mon projet ne génère plus de DLL est ce que c'est du au faite que j'utilise le mode unsafe.

    Pour info j'aimerai ajouter la dll pour créer un web service.

+ Répondre à la discussion
Cette discussion est résolue.

Discussions similaires

  1. [VB.NET 1.1] [Thread] Méthode invoke
    Par toniolol dans le forum Windows Forms
    Réponses: 5
    Dernier message: 15/02/2006, 16h04
  2. org.apache.axis.client.invoke() en exception
    Par ep31 dans le forum Services Web
    Réponses: 2
    Dernier message: 27/01/2006, 15h26
  3. [C#]Comment utiliser P/Invoke ?
    Par pataphysicien dans le forum C#
    Réponses: 3
    Dernier message: 19/01/2006, 01h58
  4. [SOAP] Invoke en ligne de commande
    Par ouechouech dans le forum XML/XSL et SOAP
    Réponses: 4
    Dernier message: 30/09/2005, 09h27
  5. [Com] Interface IDispatch.Invoke
    Par Laurent Dardenne dans le forum Windows
    Réponses: 4
    Dernier message: 15/06/2004, 22h51

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