2011-07-05 4 views
1

Tout d'abord quelques introductions: Je travaille actuellement sur une chose de compatibilité C++ qui signifie être en mesure d'exécuter des projets avec différentes options de compilateur avec l'autre. Par conséquent, je tester avec une DLL de libération et une application de débogage liant à cet autre projet. La plupart des problèmes surviennent lorsque vous utilisez STL, donc je dois m'assurer que les deux projets utilisent uniquement leur propre version de la STL. Thatswhy J'ai une classe wrapper qui peut être construite à partir de std :: vectors, std :: lists et ainsi de suite mais qui ne contient qu'un tableau complètement compatible. Maintenant, je peux envelopper les valeurs dans un tableau et les décompresser de l'autre côté dans un objet STL valide.violation d'accès étrange au vecteur indexeur

Maintenant, pour obtenir un peu plus près à la question: Il y a des classes qui contiennent STL, mais doivent également être enveloppé dans un tableau. Donc, je dois également envelopper l'objet STL interne, ce qui signifie ajouter une balise et l'enregistrer juste à côté de l'élément de tableau associé.

Construire cette classe d'emballage est pas un problème du tout, mais le déballage, il se bloque avec une violation d'accès dans la classe de vecteur ici:

const_reference operator[](size_type _Pos) const 
     { // subscript nonmutable sequence 

#if _HAS_ITERATOR_DEBUGGING 
     if (size() <= _Pos) 
      { 
      _DEBUG_ERROR("vector subscript out of range"); 
      _SCL_SECURE_OUT_OF_RANGE; 
      } 
#endif /* _HAS_ITERATOR_DEBUGGING */ 
     _SCL_SECURE_VALIDATE_RANGE(_Pos < size()); 

     return (*(_Myfirst + _Pos)); <---- HERE 
     } 

Le code exécution à ce moment est la suivante:

template<class T> 
struct mwContainerItem 
{ 
    T m_element; 
    void * m_tag; 
}; 

template<class T> 
class mwContainer 
{ 
    STLList ToList() 
    { 
     STLList l; 
     for(size_t i=0; i<m_size; ++i) <---- It crashes when accessing m_size 
     { 
      l.push_back(m_elements[i].m_element); <---- It also crashes when accessing m_elements 
     } 
     return l; 
    } 

    mwContainerItem<T>* m_elements; 
    size_t m_size; 
}; 

La chose curieuse à propos de cela est que je déballe une liste std :: mais elle se bloque dans std :: vector. En regardant la chose suivante, j'ai une classe contenue par un vecteur std :: et cette même classe contient une liste std :: d'une classe de base sans STL. Donc déballer signifie copier le tableau externe dans un vecteur std :: et chaque tableau interne dans une liste std ::.

Cette erreur ne se produit que lorsque j'utilise les différentes options du compilateur, l'emballage déballage und dans le projet même fonctionne très bien.

J'espère vraiment que quelqu'un peut me aider parce que je n'ai aucune idée.

Cordialement

+0

Malheureusement, je crois qu'il n'y a aucun moyen de contourner cela sans compiler avec les mêmes options. Voir: http://stackoverflow.com/questions/4446620/returning-strings-from-dll-functions – Maxpm

+0

Il y a certaines choses que vous devez savoir, mais après avoir apporté quelques modifications à mon code, j'ai pu le compiler avec ce méthode. Mais il commence à se planter sur un simple 'récursion wrapping' où je ne vois aucun problème si le concept fonctionne pour un exemple sans objet STL interne. –

+0

@Marcel Pourquoi considérez-vous les tableaux compatibles avec différentes options d'emballage? Habituellement, ils ne sont pas – user396672

Répondre

1

Avez-vous vraiment besoin de deux versions de STL? Je veux dire, construisez-vous les deux projets avec deux compilateurs différents, et deux implémentations STL différentes? Lorsque vous mélangez des versions de débogage et de version, le problème vient généralement de deux tas différents. Ensuite, essayer de libérer de la mémoire allouée dans un module dans l'autre, provoquera une erreur. Si c'est le cas, vous pouvez essayer une autre approche - les deux utilisent le même tas.

Si vous avez le contrôle sur les deux projets, vous pouvez exporter un allocateur (et deallocator correspondant) de la DLL et l'utiliser dans le fichier EXE. De cette façon, la gestion de la mémoire sera effectuée sur un seul segment et le type de construction n'aura aucune importance. Vous pouvez l'utiliser dans operator new, dans un vecteur/liste allocator etc.

Cela ne résoudra probablement pas les problèmes d'emballage (qui change les paramètres d'emballage de toute façon? ...), mais c'est quelque chose que vous voulez lorsque vous utilisez plus d'un tas .

+0

Oui, j'ai vraiment besoin de deux versions de STL. Ne vous inquiétez pas du fait que j'utilise deux tas parce que j'ai trouvé un moyen de gérer l'allocation de mémoire. Que voulez-vous dire exactement par les paramètres d'emballage? J'ai parlé des différences de réglage du compilateur comme dans Debug et Release qui rendent difficile la compilation. –

+0

@Marcel Bonzelet Je me réfère à l'alignement des données, soit en utilisant [pragma pack] (http://msdn.microsoft.com/fr-fr/library/2e70t5y1 (v = VS.100) .aspx), ou le [/Zp](http://msdn.microsoft.com/en-us/library/xh3e3fd0(v=VS.100).aspx) basculer. Assurez-vous qu'ils sont identiques - si vous ne savez pas ce qu'ils font, il n'y a vraiment aucune raison pour qu'ils n'aient pas le même défaut. – eran

+0

J'utilise la valeur par défaut dans les deux projets. –