CodeGuru Home VC++ / MFC / C++ .NET / C# Visual Basic VB Forums Developer.com
Page 2 of 3 FirstFirst 123 LastLast
Results 16 to 30 of 37
  1. #16
    Join Date
    Apr 2004
    Location
    England, Europe
    Posts
    2,492

    Re: problem with freeing memory in dll

    Quote Originally Posted by couling View Post
    you need to stop using vartual function calls across exe/dll boundaries or stop using Borland
    Calling virtual functions across DLL boundaries is how COM works, any game which uses Direct X does it.
    My hobby projects:
    www.rclsoftware.org.uk

  2. #17
    Join Date
    Nov 2009
    Location
    California
    Posts
    31

    Re: problem with freeing memory in dll

    ok so i think i've gotten it fully working without crashes now, although honestly i don't know why this works. ive defined the class member functions in the header as virtual, and then static loaded the lib file instead of using LoadLibrary with the dll. any thoughts on why using the static lib file is making the difference? i understand why/when to use a static lib but im just confused on why that would make it stop crashing compared to using LoadLibrary/FreeLibrary...
    Thanks for all the replies and help, much appreciated. i was so surprised to get responses so fast you guys rock!

  3. #18
    Join Date
    Nov 2007
    Location
    Birmingham, England
    Posts
    157

    Re: problem with freeing memory in dll

    As far as I can see, there's no reason for it to crash in the first place, just Borland doing something weird.

    It makes sense for linking in the dll's lib file to have a difference because I found that removing "FreeLibrary" (really bad practice) stopped it. By linking in the lib file you delay the dll being freed from memory until your program has completely finished... it can't crash after that.



    Quote Originally Posted by Zaccheus View Post
    Calling virtual functions across DLL boundaries is how COM works, any game which uses Direct X does it.
    I've never used com or direct X so I couldn't comment, but it raises one question to me:
    How does that work between different compilers?
    It's my understanding that anything object orientated cant be used as a DLL interface unless both DLL and calling code were written with the same compiler.
    Far from least on the list of problems is that OO name mangling is completely non-standard. Are you sure it doesnt effectively just use function pointers?
    Last edited by couling; November 14th, 2009 at 05:53 AM.
    Signature
    Please use: [ code ][/ code ] tags and reasonably correct tabbing. They really help us read your code
    End Signature

  4. #19
    Join Date
    Apr 2004
    Location
    England, Europe
    Posts
    2,492

    Re: problem with freeing memory in dll

    Quote Originally Posted by couling View Post
    How does that work between different compilers?
    It's my understanding that anything object orientated cant be used as a DLL interface unless both DLL and calling code were written with the same compiler.
    Or unless both follow the exact same standard.

    Microsoft have specified how COM interfaces are implemented, so any compiler vendor can ensure that their compiler is compatible.

    And yes internally it does end up being just function pointers. You can even call COM objects from C using structures containing function pointers.

    For example, here's a super simple COM interface:

    Code:
    struct IDendros0200Content1 : public IUnknown
    {
        virtual HRESULT STDMETHODCALLTYPE get_Parent(IDendros0200Element1 **theParent) = 0;
    };
    The same can be expressed in C as:

    Code:
    struct IDendros0200Content1Vtbl
    {
        // IUnknown base class virtual functions
    
        HRESULT ( STDMETHODCALLTYPE *QueryInterface )(IDendros0200Content1 * This, REFIID riid, void **ppvObject);
        ULONG ( STDMETHODCALLTYPE *AddRef )(IDendros0200Content1 * This);       
        ULONG ( STDMETHODCALLTYPE *Release )(IDendros0200Content1 * This);
    
        // IDendros0200Content1 virtual functions
            
        HRESULT ( STDMETHODCALLTYPE *get_Parent )(IDendros0200Content1 * This, IDendros0200Element1 **theParent);
    };
    
    struct IDendros0200Content1
    {
        struct IDendros0200Content1Vtbl* lpVtbl;
    };
    Last edited by Zaccheus; November 14th, 2009 at 06:21 AM.
    My hobby projects:
    www.rclsoftware.org.uk

  5. #20
    Join Date
    Nov 2007
    Location
    Birmingham, England
    Posts
    157

    Re: problem with freeing memory in dll

    You've sort of undone your own statement there by demonstrating that not all COM programs use virtual functions. The fact that some do is a hack in the compiler. A reasonably elagent hack I'll grant, but you cant garuntee every compiler has it.

    In implamentation outside COM development, compilers have a myriad of ways to implament virtual functions and the way any particular compiler does it is usually unclear to a developer.
    Last edited by couling; November 14th, 2009 at 06:55 AM.
    Signature
    Please use: [ code ][/ code ] tags and reasonably correct tabbing. They really help us read your code
    End Signature

  6. #21
    Join Date
    Apr 2004
    Location
    England, Europe
    Posts
    2,492

    Re: problem with freeing memory in dll

    It's not a hack, just a way of implementing virtual functions in plain C which follows the documented structure used by COM.

    The point of my original statement was that using virtual functions of objects which came from another DLL is not unusual in Windows programming. No matter how you use it, via C++ virtual functions which conform to COM's standard, or via C structures which conform to COM's standard, games which use Direct X do call the functions exposed from another DLL via that mechanism.

    For reference, here are two very good articles about COM:
    http://www.codeproject.com/KB/COM/comintro.aspx
    http://www.codeproject.com/KB/COM/comintro2.aspx
    Last edited by Zaccheus; November 14th, 2009 at 08:15 AM.
    My hobby projects:
    www.rclsoftware.org.uk

  7. #22
    Join Date
    Nov 2007
    Location
    Birmingham, England
    Posts
    157

    Re: problem with freeing memory in dll

    You missed my point.

    The plain C isn't a hack. Its just plain old callback functions as they existed before the days of OO. Its explicit and doesnt rely on the specific compiler to make it work so if you took it to any other windows C++ compiler, the code would still run.

    The hack is a C++ compiler which implaments virtual functions in a way that conveniently mimics the model of callback functions in exactly the way that's expected by the COM document structure. From the point of view of a C++ compiler, it has never been standardised how the "this" pointer should be passed, or where the callback function pointers for an object are stored. It's a Microsoft hack.

    Some compilers don't even store the function pointers inside the object!
    Take Borland, the compiler this discussion thread started with. With borland compile the following code:
    Code:
    #include <iostream>
    
    using namespace std;
    
    class X {
    	virtual int foo() = 0;
    };
    
    class Y {
    	virtual int foo() = 0;
    	virtual int bar() = 0;
    };
    
    int main(int argc, char* argv[])
    {
    	cout << sizeof(X) << ", " << sizeof(Y);
    	return 0;
    }
    The resulting program will print "4, 4".

    If this was to compile things in such a way as to be compatible with COM it would have to print "4, 8" because it would have to allocate space for both foo() and bar().
    Unless Borland can somehow magically detect that you're compiling a DLL for use with COM, then using virtual functions wont work!

    Hope this clarifies things a little.
    Last edited by couling; November 14th, 2009 at 01:48 PM.
    Signature
    Please use: [ code ][/ code ] tags and reasonably correct tabbing. They really help us read your code
    End Signature

  8. #23
    Join Date
    Apr 2004
    Location
    England, Europe
    Posts
    2,492

    Re: problem with freeing memory in dll

    Quote Originally Posted by couling View Post
    The hack is a C++ compiler which implaments virtual functions in a way that conveniently mimics the model of callback functions in exactly the way that's expected by the COM document structure.
    Quick note; As far as I know, it was the other way around: Microsoft based the COM structure on how virtual funtions were implemented in their Visual C++ compiler. Not that this matters.

    From the point of view of an ANSI C++ compiler, I agree with you. According to the ANSI/ISO standard, any C++ compiler has huge freedom to implement function calls, structure layouts, and type sizes in different ways.

    Having said that, it would be impossible to call any Windows API functions if compilers written for Windows didn't follow certain OS specific standards. The __stdcall calling convention is an example, and the internal layout of the C structures used by the Windows API has to be implemented the same for every compiler. For Windows C++ compilers to also follow Microsoft's way of implementing virtual functions is not much different.

    Quote Originally Posted by couling View Post
    Code:
    #include <iostream>
    
    using namespace std;
    
    class X {
    	virtual int foo() = 0;
    };
    
    class Y {
    	virtual int foo() = 0;
    	virtual int bar() = 0;
    };
    
    int main(int argc, char* argv[])
    {
    	cout << sizeof(X) << ", " << sizeof(Y);
    	return 0;
    }
    The resulting program will print "4, 4".
    That is correct. Look at the code I posted again. The interface IDendros0200Content1 has a pointer to the virtual function table. No matter how many functions there are, the interface will always have the same size.
    Last edited by Zaccheus; November 14th, 2009 at 03:40 PM.
    My hobby projects:
    www.rclsoftware.org.uk

  9. #24
    Join Date
    Nov 2007
    Location
    Birmingham, England
    Posts
    157

    Re: problem with freeing memory in dll

    Hmm, for some reason I read it as being inline rather than as a pointer to the vtable. Not sure what I was drinking to make me see that . That kinda makes my last two posts make a lot less sense since I've long been aware of the vtable technique.

    Still its an interesting point which appears to need a lot more reading on my part. Up until now all the infomation I've read suggests never using object orientated stuff in a dll interface when working across compilers due to a lack of standardisation. This is the main reason given for compiler vendors making no attempt to standardise name mangling as an attempt to discourage programmers doing so.

    Also I'd love to know what Borland was doing to mess up virtual functions with dynamically loaded Dlls.
    Signature
    Please use: [ code ][/ code ] tags and reasonably correct tabbing. They really help us read your code
    End Signature

  10. #25
    Join Date
    Apr 2004
    Location
    England, Europe
    Posts
    2,492

    Re: problem with freeing memory in dll

    Quote Originally Posted by couling View Post
    Up until now all the infomation I've read suggests never using object orientated stuff in a dll interface when working across compilers due to a lack of standardisation.
    Generally speaking, I absolutely agree. Never using 'new' in one DLL and 'delete' in another, for example.

    It is probably only due to the widespread use of COM that the virtual table implementation became standardised on Windows at all (note this only applies to single inheritance!).

    I would have preferred a vendorspecific keyword ( struct __interface IMyInterface {}; ) to be used when declaring such interfaces, to make it explicit, just like __stdcall.
    My hobby projects:
    www.rclsoftware.org.uk

  11. #26
    Join Date
    Apr 2004
    Location
    England, Europe
    Posts
    2,492

    Re: problem with freeing memory in dll

    Quote Originally Posted by couling View Post
    So What's making it crash?
    A little testing revealed that calling any virtual function in the DLL would cause a crash iif FreeLibrary was used to unload the dll. The crash actually occurred at the very end of your program (when main() called return 0; ). My only explanation is that its being caused by a little black magic going on in the way Borland calls virtual functions.
    I don't have a Borland compiler anymore otherwise I'd try this myself ...

    Does the program still crash if we add the following function to the DLL and call that instead of calling release() ? Also release() should be declared __stdcall just to be safe.

    Code:
    extern "C" void MYAPI __stdcall DeleteDllObject(DllObjectParent* obj)
    {
        delete dynamic_cast<DllObject*>(obj);
    }
    I'm wondering if a moderator should move this thread to the Windows API section.
    My hobby projects:
    www.rclsoftware.org.uk

  12. #27
    Join Date
    Nov 2007
    Location
    Birmingham, England
    Posts
    157

    Re: problem with freeing memory in dll

    Apologies for my mis information guys. Seems that using Dynamic load DLLs with borland is pretty much foo-bared up. Just I was unlucky to get ~10 tests that ran fine, the only feature obveously different between those that did and those that didn't was the virutal function thing.

    The more tests I run the more I get what appear to be random crashes. Changing insugnificant parts of the code just cause it to a crash.
    Signature
    Please use: [ code ][/ code ] tags and reasonably correct tabbing. They really help us read your code
    End Signature

  13. #28
    Join Date
    Nov 2009
    Location
    California
    Posts
    31

    Re: problem with freeing memory in dll

    to that last post by couling, now you know what i was going through lol.
    here's a link to a site i had found about exporting classes from a dll.
    http://www.codeproject.com/KB/cpp/ho...p_classes.aspx
    one other question for you guys, what do you suggest if i don't want to use the
    lib file like if me/someone else want to use it but only has the header file and the dll?
    i never really found a fix for that..
    if i can tonight or tomorrow ill try out what zaccheus mentioned. i saw that actually on the tutorial i linked to above, under the heading 'The C Language Approach' but as far as i can tell the example didn't use it on the part under 'C++ Mature Approach'
    Last edited by rhboarder; November 15th, 2009 at 07:09 PM. Reason: added text

  14. #29
    Join Date
    Nov 2007
    Location
    Birmingham, England
    Posts
    157

    Re: problem with freeing memory in dll

    Most compiler suits come with a program to automatically generate .lib files from the dll (This is called "implib" under borland). With some compilers such as MinGW you can pass the Dll in as a command line option and it just implies the infomation that the .lib would provide. Usually its easier to distribute the .lib file with the dll if you can tho.

    Edit: Oh, implib can also create a .lib from a .def text file, so you can control it if you're getting problems automatically implying from a dll
    Last edited by couling; November 15th, 2009 at 07:47 PM.
    Signature
    Please use: [ code ][/ code ] tags and reasonably correct tabbing. They really help us read your code
    End Signature

  15. #30
    Join Date
    Nov 2009
    Location
    California
    Posts
    31

    Re: problem with freeing memory in dll

    thanks couling. two things: one method that works is as zaccheus said using another external
    function in the dll to delete the object. secondly, and this actually fixed my original
    problem with LoadLibrary/FreeLibrary. I was looking at the documentation for
    FreeLibrary and it says when it is called it will call DllMain. i didn't previously have
    that so i added the following -
    Code:
    BOOL WINAPI DllEntryPoint(HINSTANCE, DWORD, LPVOID)
    {
    	return TRUE;
    }

Page 2 of 3 FirstFirst 123 LastLast

Posting Permissions

  • You may not post new threads
  • You may not post replies
  • You may not post attachments
  • You may not edit your posts
  •  





Click Here to Expand Forum to Full Width

Featured