c ++ - hukommelsesadressen til en medlemsvariabel for argumentobjekter ændres, når dll-funktionen hedder

Indlæg af Hanne Mølgaard Plasc

Problem



klasse SomeClass
    {

        //nogle medlemmer

        MemberClass one\_of\_the\_mem\_;
    }


Jeg har en funktion foo( SomeClass *object ) inden for en dll, den bliver kaldt fra en exe.


Problem


adressen på one\_of\_the\_mem\_ ændres i løbet af det tidspunkt, hvor dll-opkaldet afsendes.


Detaljer :


før opkaldet er lavet (fra exe):


             '&(this).one\_of\_the\_mem\_' - `0x00e913d0`


efter - i selve dll:


             '&(this).one\_of\_the\_mem\_' - `0x00e913dc`


Objektets adresse forbliver konstant. Det er kun det medlem, hvis adresse skiftes med c hver gang.


Jeg vil have nogle pointers om, hvordan kan jeg fejle dette problem.


Kode:


Kode fra Exe



  stat=modul-> init (dette,
                                  object\_a,
                                             &Amp; object\_b,
                                             object\_c,
  con\_dir
                                           );



Kode i DLL


Status\_C ModuleClass( SomeClass *object, int index, Config *conf, const char* name)
{
    \_ASSERT(0); //DEBUGGING HOOK
    ...


Opdater 1:


Jeg sammenlignede medlemmernes forskydninger efter Michael's instruktion, og de er de samme i begge tilfælde.


Opdatering 2:


Jeg fandt en måde at dumpe klasselayoutet og bemærkede forskellen i størrelse, jeg er nødt til at regne ud, hvorfor foregår det dog.


linked er det spørgsmål, jeg fandt at dumpe klasselayout.


Opdatering 3:
Klasses layoutforskel mellem exe og dll, men ved ikke hvorfor endnu

Endelig opdatering : Løst problemet, meget takket være Michael Burr.


det viste sig at en af ​​bygningen brugte 32 bit tid, \_USE\_32BIT\_TIME\_T blev defineret i den og den anden bruger 64 bit tid. Så det genererede det forskellige layout for objektet, vedhæftet er forskellen fil.


Diff i to klasser på grund af sizeof` time\_t

Bedste reference


Din DLL blev sandsynligvis samlet sammen med forskellige sæt kompileringsindstillinger (eller måske endda en lidt anden headerfil), og klasselayoutet er anderledes som følge heraf.


For eksempel, hvis man blev bygget ved hjælp af fejlfindingsflagger og andre var det ikke, eller selvom der blev brugt forskellige kompilatorversioner. For eksempel kan biblioteker, der anvendes af forskellige compilerversioner, have subtile forskelle, og hvis din klasse indeholder en type, der er defineret af biblioteket, skal du kunne have forskellige layouter.


Som et konkret eksempel er Microsofts kompilator iteratorer og containere følsomme over for frigivelse/fejlfinding, \_SECURE\_SCL on/off og \_HAS\_ITERATOR\_DEBUGGING on/off indstilling (i det mindste om VS 2008 - VS 2010 kan have ændret noget af dette til en vis omfang). Se http://connect.microsoft.com/VisualStudio/feedback/details/352699/secure-scl-is-broken-in-release-builds for nogle detaljer. [7]


Disse slags problemer gør brug af C ++-klasser på tværs af DLL-grænser lidt mere skrøbelige end ved brug af lige C-grænseflader. De kan også forekomme i C-strukturer, men det ser ud til, at C ++-biblioteker har disse forskelle oftere (jeg synes, at det er naturen at have en rigere funktionalitet).


Et andet layout-ændringsproblem, der opstår med det samme, har en anden strukturpakkeindstilling i kraft i de forskellige kompiler. En ting der kan 'skjule' dette er, at pragmas ofte bruges i overskrifter for at indstille strukturpakker til en bestemt værdi, og nogle gange kan du komme over et overskrift, der gør dette uden at ændre det tilbage til standardværdien (eller mere korrekt den tidligere indstilling ). Hvis du har en sådan overskrift, er det nemt at få det med i bygningen til et modul, men ikke en anden.



Andre referencer 1


det lyder lidt koldt, du skal vise mere kode, den skal 'flytte', hvis den bliver sendt af ref, det lyder mere som en kopi af den bliver lavet, og at have medlemsfunktionen kaldet.


Måske er DLL-versionerne kompileret mod en anden version, som du refererer til. Kontroller og sørg for, at overskriftsfilen er for samme version som dll.


Genompil biblioteket, hvis du kan.