2009-04-02 7 views
4

Je reçois un comportement vraiment étrange dans l'une des DLL de mon application C++. Cela fonctionne et se charge bien jusqu'à ce que j'inclue un seul fichier en utilisant #include dans le fichier principal de la DLL. Je puis reçois ce message d'erreur:LoadLibrary échoue lors de l'inclusion d'un fichier spécifique pendant la construction de la DLL

composants de chargement de D: /Targets/bin/MatrixWorkset.dll Impossible de charger « D: /Targets/bin/MatrixWorkset.dll »: Impossible de charger MatrixWorkset bibliothèque: l'accès à la mémoire non valide emplacement.

Maintenant, j'ai cherché et cherché à travers le code et google et je ne peux pas comprendre ce qui se passe. Jusqu'à présent, tout était dans une seule DLL et j'ai décidé de le diviser en deux plus petites. Le fichier qui cause les problèmes fait partie de l'autre seconde bibliothèque (qui se charge bien).

Toutes les idées seraient vraiment appréciées. Merci, Jaco

+0

un accès à la mémoire partagée? – CookieOfFortune

+0

Montre du code, un #include peut faire n'importe quoi. – Ismael

+0

OK, après plus de débogage. Le fichier (avec la classe MatrixVariable) n'a même pas besoin d'être inclus dans d'autres fichiers. J'ai juste besoin de l'ajouter au fichier make pour la DLL qui casse la DLL. MatrixVariable hérite d'une classe à l'intérieur de la seconde DLL et c'est à peu près tout. Cela a fonctionné en employant seulement 1 DLL –

Répondre

2

Est-il possible qu'un en-tête inclue un commentaire #pragma (lib, "somelibrary.lib") quelque part? Si c'est le cas, il essaie automatiquement d'importer une bibliothèque.

Pour résoudre ce problème je commencerais par regarder le binaire avec depends (http://www.dependencywalker.com/), pour voir s'il y a des dépendances de DLL que vous ne vous attendez pas. Si vous trouvez quelque chose et vous êtes dans Visual Studio, vous devez activer "Show Progress" AKA/VERBOSE sur l'éditeur de liens.

Étant donné que vous obtenez l'accès non valide à l'emplacement de mémoire, il est possible qu'il y ait quelque chose dans le DLLMAIN ou un initialiseur statique qui se bloque. Pouvez-vous simplifier le MatrixWorkset.dll (en supposant que vous l'avez écrit)?

+0

Je suis assez sûr qu'il n'y a pas un #pragma dans le dossier inclus puisque je l'ai écrit moi-même et cela fonctionne quand inclus dans une DLL différente qui l'emploie également. Dans la marchette de dépendance et tout semble bien. La DLL non-travail a une copie dupliquée de la DLL dépendante qui n'est pas le cas pour la DLL de travail –

+0

Aussi, j'ai simplifié MatrixWorkset.dll jusqu'au point où cela fonctionne quand je n'inclue pas l'en-tête et ensuite travaux. J'ai comparé cette copie de travail à la copie non-travail et la DLL en double est la seule différence que je peux voir ... –

6

La cause probable est un type global avec classe. Le constructeur est exécuté à partir de DllMain() et DllMain() s'exécute à son tour avant les retours LoadLibrary(). Il y a quelques restrictions sur ce que vous pouvez faire jusqu'à ce que DllMain() soit revenu.

+1

"Il y a quelques restrictions sur ce que vous pouvez faire jusqu'à ce que DllMain() soit de retour." ... tel que? Lien s'il vous plaît ... – Gili

+1

MSDN à la rescousse: http://msdn.microsoft.com/en-us/library/ms682583.aspx – MSalters

0

L'erreur que vous décrivez ressemble à une erreur d'exécution. Cette erreur est-elle affichée automatiquement par Windows ou est-ce que votre programme émet?

Je dis attacher un débogueur à votre application et trace d'où vient cette erreur. Windows ne parvient pas à charger une dépendance? Votre bibliothèque échoue-t-elle d'une manière ou d'une autre au chargement?

Si vous souhaitez appliquer/exclure ce fichier d'en-tête que vous incluez, essayez de pré-compiler votre fichier source principal avec et sans ce #include et diff les deux résultats.

0

Je ne comprends toujours pas. Permettez-moi de répondre à certaines des questions posées:

1) Windows ne manque pas de charger une dépendance, je pense que Dependency Walker montre que tout va bien. 2) J'ai joint un débogueur qui imprime essentiellement les points suivants quand il tente de charger MatrixWorkset.dll:

 
      10:04:19.234 
stdout:&"warning: Loading components from D:/ScinericSoftware/VisualWorkspace/trunk/Targets/bin/MatrixWorkset.dll\n" 
      10:04:19.234 
stdout:&"\n" 
status:Stopped: "signal-received" 
status:Stopped. 
      10:04:19.890 
stdout:30*stopped,reason="signal-received",signal-name="SIGSEGV",signal-meaning="Segmentation fault",thread-id="1",frame={addr="0x7c919994",func="towlower",args=[],from="C:\\WINDOWS\\system32\\ntdll.dll"} 
input:31info shared 
input:32-stack-list-arguments 2 0 0 
input:33-stack-list-locals 2 
input:34-stack-list-frames 
input:35-thread-list-ids 
input:36-data-list-register-values x 
      10:04:19.890 

3) MSalters: Je ne sais pas ce que vous entendez un « type global avec classe » . Le fichier qui pose les problèmes a été inclus dans une DLL différente dans laquelle il a bien fonctionné et la DLL chargée avec succès.

C'est en haut du fichier MatrixVariable.h:

#include "QtSF/Variable.h" // Located in depending DLL (the DLL in which this file always lived. 
#include "Matrix.h" // File located in this DLL 
#include "QList"  // These are all files from the Qt Framework 
#include "QModelIndex" 
#include "QItemSelection" 
#include "QObject" 

using namespace Zenautics; 
using namespace std; 

class MatrixVariable : public Variable 
{ 
    Q_OBJECT 
    Q_PROPERTY(int RowCount READ rowCount WRITE setRowCount) 
    Q_PROPERTY(int ColumnCount READ columnCount WRITE setColumnCount) 
    Q_PROPERTY(int UndoPoints READ undoPoints WRITE setUndoPoints) 

public: 
    //! Default constructor. 
    MatrixVariable(const QString& name, int rows, int cols, double fill_real = 0, double fill_complex = 0, bool isReal = true); 

etc., etc., etc.

Une solution possible consiste à remettre le fichier MatrixVariable dans la DLL d'origine, mais cela va à l'encontre de l'idée de scinder la DLL en parties plus petites, ce qui n'est pas vraiment une option.

0

Je reçois cette erreur de GetLastError() lorsque je ne parviens pas à charger une DLL à partir d'une ligne de commande EXE récemment. Il a l'habitude de travailler, puis j'ai ajouté du code MFC à la DLL. Maintenant, tous les paris sont désactivés.

0

Je viens d'avoir exactement le même problème. Un dll qui fonctionnait très bien, a soudainement cessé de fonctionner. Je prenais une violation d'accès dans le truc CRT qui initialise les objets statiques. Faire une reconstruction tout n'a pas résolu le problème. Mais quand j'ai commenté manuellement toutes les statistiques, l'éditeur de liens s'est plaint d'un fichier corrompu. Lien à nouveau: a travaillé. Maintenant, je peux LoadLibrary. Puis, un par un, j'ai ajouté la statique. Chaque fois, j'ai recompilé et testé une LoadLibrary. Chaque fois que ça a bien fonctionné. Finalement, toutes mes statics étaient de retour, et les choses fonctionnaient normalement.

Si je devais deviner, un fichier intermédiaire utilisé par l'éditeur de liens était corrompu (je vois que les fichiers ilk sont constamment corrompus par link.exe). Si vous le pouvez, peut-être effacer tous vos fichiers et faire une construction propre? Mais je devine que vous avez déjà compris les choses depuis qu'il est âgé de 6 mois ...

Questions connexes