Question

Quand j'appelle un code C ++ non géré de mon code C #, il me semble avoir une sorte de fuite de mémoire.
Le C ++ lit les données à partir d'un fichier en utilisant ifstream.read, et l'écrit dans un vecteur.

Cela se produit uniquement après la mise à niveau vers Windows 7, ne se produit pas sur Vista, mais si j'utilise une version de la dll native qui a été compilé sur Vista, il ne change rien!
Si je lance le même code C ++ directement, sans le interope géré, il n'y a pas de fuite de mémoire!
Si je lance le processus de gestion, mais dans le processus de vshost, il n'y a pas de fuite de mémoire!

Voici la signature d'appel:

        [DllImport(DllPath, CharSet = CharSet.Unicode)]
    [return: MarshalAs(UnmanagedType.I1)]
    public static extern bool MyMethod(
        int x, 
        string  y, 
        string  z, 
        bool    v, 
        bool    w);

et natif:

MyDll_Export bool APIENTRY MyMethod(
int x,
const wchar_t*  y, 
const wchar_t*  z,
bool v,
bool w)

Quand je l'appelle de C ++, je l'appelle comme ceci:

MyMethod(1, L"My String 1", L"My String 2", true, true)

Quand je regarde les compteurs de performance pour la mémoire gérées et non gérées, je vois que toute la mémoire vient du code non managé.
Considérant que le marshaling est assez simple, je ne comprends pas pourquoi il y a une différence entre appeler le C ++ directement ou par C #.
Je ne sais pas non pourquoi cela se produit uniquement sur Windows 7 (à la fois les installations Windows 3.5 SP1 ont .net).

Est-ce que quelqu'un a une idée quelle est la raison?

Aussi, si quelqu'un connaît un outil de profilage de la mémoire native qui fonctionne sur Windows 7, je serais heureux de savoir (pour l'instant je viens afficher sur la console toute allocation de mémoire explicite et il n'y a pas de différence).

Était-ce utile?

La solution

Je suis sûr que le problème est lié à marshaling les types de données C # à leurs homologues C ++. Puisque vous Marshaling la valeur de retour bool à une valeur signée 1 octet, peut-être vous devriez faire la même chose aux arguments de la fonction? Le type C # bool est de 4 octets, peut-être que vous y une fuite de?

En outre, en spécifiant le type non géré pour les cordes peuvent aider.

[DllImport(DllPath, CharSet = CharSet.Unicode)]
[return: MarshalAs(UnmanagedType.I1)]
public static extern bool MyMethod(
        int x,
        [MarshalAs(UnmanagedType.LPWStr)]
        [In] string y,
        [MarshalAs(UnmanagedType.LPWStr)]
        [In] string z,
        [MarshalAs(UnmanagedType.I1)]
        bool v,
        [MarshalAs(UnmanagedType.I1)]
        bool w);

Une explication pour le commentor:

Pour le C ++ type bool:

  

En général, un zéro ou à un pointeur null   valeur est convertie en faux, tout autre   valeur est convertie en true.

...

  

Les 1998 C ++ Standard Library définit   une spécialisation du vecteur   modèle pour bool. La description de   la classe indique que la   la mise en œuvre devrait emballer le   de sorte que tous les éléments bool seulement les utilisations   un bit de mémoire.

Alors, à peu près tout ce que la valeur que vous utilisez, vous obtiendrez un c ++ booléen avec la valeur true ou false.

Autres conseils

Malheureusement, une fois que vous impliquez les chaînes, pas marshalling est simple.

Nous allons avoir besoin des données supplémentaires afin de vous aider à traquer ce problème. Pouvez-vous fournir les éléments suivants

  • Méthode native Signature
  • Comment la mémoire pour les chaînes gérées en code natif?
  • Peut-être l'échantillon C ++ où vous utilisez l'API?

EDIT

Essayez la signature suivante. Cela indique au CLR de ne pas rassembler la mémoire dans les deux sens, mais passe plutôt que les données.

    [DllImport(DllPath, CharSet = CharSet.Unicode)]
    [return: MarshalAs(UnmanagedType.I1)]
    public static extern bool MyMethod(
            int x, 
            [In] string  y, 
            [In] string  z, 
            bool    v, 
            bool    w);

Je trouve l'utilisation du CLR Profiler utile lors de la recherche ma fuite de mémoire.

Êtes-vous sûr qu'il ya une fuite de mémoire?

Quelle est votre base pour déterminer la fuite de mémoire. Vous dites que vous pouvez le voir à partir des compteurs de performance, mais qu'est-ce que vous observez réellement? Voyez-vous une courbe ascendante coninously, ou qui se dépose à un niveau élevé? Une consommation élevée de mémoire est souvent confondue pour une fuite de mémoire.

BTW. Pouvez-vous vous poster C ++ définition de la fonction aussi bien?

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top