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++/CLI Discussion :

C# et Dll non managé : passage de tableau de caractère


Sujet :

C++/CLI

Vue hybride

Message précédent Message précédent   Message suivant Message suivant
  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 3
    Par défaut C# et Dll non managé : passage de tableau de caractère
    Bonjour A tous,

    J'ai besoin de votre aide. Pourriez vous m'aider s'il vous plait ?

    Je vous explique :
    J'ai repris un code qui initialement en C++ non managé fait appel à une DLL elle non plus non managé. J'ai les sources des 2 (programme + DLL) et je dois passé le programme en C# et pas la DLL (je peux néanmoins modifier la DLL pour l'adapter si besoin).
    Le source fait appel à une fonction de la dll en lui passant un tableau de caractère que la fonction doit retourner rempli (il est utilisé dans la DLL en tant que char*[10]). Le passage se fait par un pointeur char *.

    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
     
    //Programme C++
    {
    	char *pTest[10];
     
    	for (i=0; i<10; i++)
    	pTest[i] = (char *)malloc(100);
    	m_test->foo((char *)pTest);
    }
     
    //DLL C++
    int fooclass::foo(char *pDevList)
    {
     
    AFX_MANAGE_STATE(AfxGetStaticModuleState())
     
    char **pDeviceList = (char **)pDevList;
     
    RempliTableau(pDeviceList);
    }
    Et la je me retrouve coincé. Comment puis récupérer mon tableau de char.
    J'ai utilisé des string en C# et wchar_t * en passage de paramêtre mais soit j'ai un pb de mémoire soit ce que je récupere n'ai pas bon ou les 2:

    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
    //Programme C#
    {
    	string[] Device = new string[100];
     
    	[DllImport("fooDll.DLL", EntryPoint = "?foo@fooclass@@QAEHQAPA_W@Z", CharSet = CharSet.Auto)]
    	public static extern int foo([In ,Out] String[] pDevList);
     
    	public void test()
    	{
    		foo(Device);
    	}
    }
     
    //DLL C++
     
    //.h
     
    class __declspec(dllimport) fooClass
    {
    public:
     
    int foo (wchar_t *pDevList[100]);
    }
     
     
    //.cpp
     
     
    int fooClass::foo(wchar_t *pDevList[100])
     
    {
    	AFX_MANAGE_STATE(AfxGetStaticModuleState());
     
    	CString pDeviceList[100];
    	wchar_t **pDevListLocal;
    	pDevListLocal = (wchar_t **)pDevList;
     
    	for (i=0; i<100; i++)
    	{
    	pDevListLocal[i] = (wchar_t *)malloc(1000);
    	mbstowcs(pDevListLocal[i],"\0",1);
    }

    Si jusqu'à la fin de la fonction foo de la DLL ça se passe bien, le retour de la fonction est problematique.
    1- il ne peut pas me retourner un tableau de 100 string? complet (il plante pour un pb mémoire)
    2- Ce que je récupere ne correspond pas au niveau caractère à ce que je dois avoir...


    Est ce quelqu'un aurait une idée et me donner un petit coup de pouce s'il vous plait ?

    Merci d'avance.

    Devajax13

  2. #2
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Par défaut
    si j'ai bien compris, ton problème est de récupérer un tableau de wchar_t, rempli coté natif, dans ton programme C# ?

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 3
    Par défaut
    Bonsoir Nico,
    En fait c'est un tableau de wchar_t*.
    Si au départ c'était un tableau de char* dans la DLL, je l'ai modifié en wchar_t* pour utiliser un tableau de String en C# au lieu d'utiliser un tableau à 2 dimensions de char.

    Merci

    cdlt

  4. #4
    Rédacteur
    Avatar de nico-pyright(c)
    Profil pro
    Inscrit en
    Octobre 2003
    Messages
    6 414
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2003
    Messages : 6 414
    Par défaut
    Je ne connais pas de mécanisme qui fait tout tout seul malheureusement
    et bien souvent, il faut spécifier les tailles en paramètres.

    Regarde cet exemple, ici je met les tailles en dur (enfin, surtout la taille du tableau, la taille des chaines, on s'en fout un peu)

    J'ai une dll en C qui exporte une fonction :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
    #include <stdio.h>
     
    extern "C" __declspec(dllexport) void demo(wchar_t ** &tab)
    {
    #define SIZE 10
    	tab = new wchar_t* [SIZE];
    	for (int i = 0; i < SIZE ; i++)
    	{
    		tab[i] = new wchar_t[20];
    		swprintf(tab[i], L"chaine : %i", i);
    	}
    }
    et voici le code C# qui permet de récupérer le tableau
    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
            [DllImport("demoWchar.dll")]
            public static extern void demo(out IntPtr buff);
     
            static void Main()
            {
                IntPtr test;
                demo(out test);
     
                int tailleTableau = 10;
                IntPtr[] tabPointeur = new IntPtr[tailleTableau];
                Marshal.Copy(test, tabPointeur, 0, tailleTableau);
                for (int i = 0; i < tailleTableau; i++)
                {
                    Console.WriteLine(Marshal.PtrToStringUni(tabPointeur[i]));
                }
            }
    On note qu'à chaque fois, j'ai mis 10 en dur comme taille de tableau ... en général, c'est un paramètre qu'on fait transiter dans les appels de fonction

    Attention, ici la mémoire n'est pas libérée, il faudrait une méthode dans la DLL C qui libère le pointeur

  5. #5
    Futur Membre du Club
    Profil pro
    Inscrit en
    Mars 2008
    Messages
    3
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Mars 2008
    Messages : 3
    Par défaut
    C'est exactement ce qu'il me fallait.

    Merci beaucoup.

    Devajax13

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

Discussions similaires

  1. Réponses: 12
    Dernier message: 23/05/2007, 21h40
  2. Réponses: 3
    Dernier message: 19/02/2007, 15h07
  3. Dll managé utilise une dll non managé
    Par DAMVAL dans le forum C++/CLI
    Réponses: 3
    Dernier message: 28/11/2006, 10h36
  4. Réponses: 2
    Dernier message: 09/08/2006, 15h06
  5. Réponses: 12
    Dernier message: 30/01/2006, 21h13

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