2009-11-24 53 views
1

J'ai une classe abstraite dans ma DLL.Puis-je changer d'interface dll sans recompilation exe-fichier?

class Base { 
    virtual char * First() = 0; 
    virtual char * Second() = 0; 
    virtual char * Third() = 0; 
}; 

Cette bibliothèque dinamique et cette interface sont utilisées depuis longtemps. Il y a une erreur dans mon code. Maintenant, je veux changer cette interface

class Base { 
    virtual const char * First() const = 0; 
    virtual const char * Second()  = 0; 
    virtual  char * Third() const = 0; 
}; 

Un programme EXE utilise ma DLL. Est-ce que le programme EXE fonctionnera sans recompilation? Envisager des modifications dans chaque ligne de nouvelle interface indépendamment.

Remarque: bien sûr, programme-EXE ne change pas les résultats des fonctions.

Répondre

1

Cela ne devrait pas fonctionner, mais vous ne connaissez jamais votre chance.

En raison de la surcharge, char *First() et const char *First() const sont des fonctions différentes. Vous pourriez avoir les deux dans la même classe. Ainsi, tout système de dénigrement doit les mettre en correspondance avec des noms différents, ce qui est évidemment un problème en ce qui concerne la liaison.

Mais, ce sont des appels virtuels, et vous avez trois fonctions remplacées par leurs équivalents dans le même ordre. Je ne connais pas les détails du schéma vtable de MSVC, en particulier si les offsets sont déterminés statiquement ou liés dynamiquement. Si le premier, il est possible que l'exe peut lier contre le nouveau vtable. Les pointeurs de fonction peuvent simplement fonctionner, car la convention d'appel ne dépend pas de la qualification cv (c'est-à-dire qu'un const char* est retourné de la même façon qu'un char* est, et const est passé de la même manière non-const c'est).

Même si cela fonctionne, je ne voudrais pas m'en prévaloir à moins que ce soit quelque chose que MS spécifiquement adresse et garantit.

+0

Vous écrivez "la convention d'appel ne dépend pas de la qualification cv". Telle est la question. Est ce bien? –

+0

C'est pour Win32. 'this' est passé dans ECX que ce soit const ou non, et un retour' char * 'est dans EAX, que ce soit const ou non. Mais cela ne suffit pas pour que la liaison fonctionne. Comme je le dis, je ne connais pas les vtables de MSVC, et je ne connais pas non plus la convention d'appel Win64 (si vous avez une version 64 bits). –

+0

Pourquoi seul le quatrième homme a compris ma question? - rhétorique. –

0

depuis que vous changez votre interface, vous devez recompiler (je pense)

0

ne fonctionnera probablement pas. Bien que le moyen le plus facile de savoir à coup sûr est de l'essayer et de voir

+0

Qu'en est-il du futur? Je vais changer VS2008 à VS2010, VS2015, VS2137 somewhen. –

+0

+ 1 pour suggérer de l'essayer – ChrisF

+6

Je ne pense pas essayer est la bonne façon. Cela pourrait fonctionner ou il pourrait silencieusement détruire d'autres données. – EFraim

3

Votre EXE pourrait changer le résultat de la fonction puisqu'il était char*. Maintenant, il est const char*. Et changer l'objet const conduira à un comportement non défini selon C++ standard 7.1.5.1/3-4:

Un pointeur ou une référence à un type de cv qualifié ne doit pas en fait point ou se référer à un objet cv qualifié, mais il est traité comme s'il le faisait; un chemin d'accès qualifié const ne peut pas être utilisé pour modifier un objet même si l'objet référencé est un objet non-const et peut être modifié via un autre chemin d'accès. [Note: les qualificatifs cv sont pris en charge par le système de types, de sorte qu'ils ne peuvent pas être subvertis sans le cast (5.2.11). ]

Sauf que tout membre de classe déclaré mutable (7.1.1) peut être modifié, toute tentative de modification d'un objet const pendant sa durée de vie (3.8) entraîne un comportement indéfini.

+0

EXE-programme ne change pas les résultats des fonctions. –

0

Je ne pense pas que cela fonctionnera. La modification de l'interface d'une DLL nécessite généralement la recompilation de l'exécutable lié à celle-ci.

En outre, vous devrez probablement apporter des modifications au code dans l'exécutable, car vous avez modifié les signatures de fonction.Enfin, si vous souhaitez mettre à jour/ajouter une interface, il est préférable de sous-classer l'interface d'origine. Cela empêchera tout code existant de se casser.