Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
M

Matthew Busche

@Matthew Busche
About
Posts
13
Topics
4
Shares
0
Groups
0
Followers
0
Following
0

Posts

Recent Best Controversial

  • Heap Hell
    M Matthew Busche

    I have spent the last 24 hours tracking down a heap corruption problem. I think I now know vaguely what the problem is, but it has made it clear I have no idea what I'm doing when it comes to heap usage with DLLs under windows. I am hoping some seasoned windows programmer out there can first look at my sad story below, and then either educate me as to the do's and don'ts of heap usage with DLLs under windows or point me to an article or book that will educate me. I'm not looking to be an expert, but I don't want to hit any more snafus like this one. MY SAD STORY: I'm working on my first windows DLL. I have an exported function that looks much like this one:

    void \_\_declspec(dllexport) getCommandString(std::string& commandString);
    

    In case it's not obvious, usage of this function is for the application to pass in a string by reference, then some code in the DLL sets it for you. Perhaps you already know my problem. If you do, YOU are the person I hope to hear from. But I'll finish my sad story for those of you who don't. So I had some application code that called this function, much like this:

    void doSomething()
    {
        std::string commandString;
        getCommandString(commandString);
        // do some stuff with the string
        return;
    }
    

    doSomething() fails at the return statement with an assertion failure when memory for commandString was being freed. Digging into the stack trace I found the assertion failure was occuring somewhere in the implementation of this system call:

    HeapValidate( \_crtheap, 0, pHdr(pUserData) );
    

    I read the docs for HeapValidate and discovered you could set the thrid arg to NULL to force the entire heap to be validated. So I immediately had the idea of sprinkling my own calls to HeapValidate throughout my code to track down the time when I was corrupting the heap. But then I couldn't figure out where to get the symbol _crtheap. I could see it in the debugger, but couldn't find it declared in any headers that came with VC6. So I says to myself, "I'll just hard code the address since surely _crtheap won't change values from run to run." But this caused me problems too. Eventually I figured out that that value of the global symbol _crtheap was changing within a single run! After some additional contemplation, I says to myself, "Perhaps there is more than one heap for my process!" Through additional experimentation, I now believe that my DLL is allocating and freeing memory

    C / C++ / MFC debugging data-structures performance help learning

  • Looking for terminology
    M Matthew Busche

    I'm working on a document and am looking to use standard terminology where possible: There are built-in data types (e.g., int, float, char*, etc) and there are objects. I'm looking for a commonly used term that refers to either. Is there such a term? Is there a name for the program initialization activity when global C++ objects are initialized at run time? (This happens before main() gets invoked I know, but what is this initialization activity called?) Thanks, Matt

    C / C++ / MFC question c++

  • My DllMain is not getting invoked.
    M Matthew Busche

    Much thanks to Peter Molnar for mailing me a completely trivial DevStudio project containing a DllMain() that got properly invoked. What I was missing (and what I had never seen documented) was the APIENTRY declaration for the DLL entry point function. The DllMain must be declared like this:

    BOOL APIENTRY DllMain(HINSTANCE , DWORD , LPVOID )

    Once those 8 pesky characters were added, it worked great. Also, for those who care, this works independently of the application type (i.e., works for both console apps and windows apps) and (as Peter said in an earlier message on this thread) works independently of how the library is loaded. (I.e., you can use either load-time dynamic linking or run-time dynamic linking.) Matt

    C / C++ / MFC tools question

  • My DllMain is not getting invoked.
    M Matthew Busche

    Peter, Thanks for your confirmation that this at least should work. So why then is my DllMain not getting invoked. Here's my current inplementation:

    #include "MyHeader.h"
    #include "windows.h"

    BOOL DllMain(HINSTANCE , DWORD pReason, LPVOID ) {
    try {
    printf("I'M HERE!\n");
    int *x = NULL;
    *x = 20;

    switch (pReason) {
    case DLL_PROCESS_ATTACH:
    MyProcessAttach();
    MyThreadAttach();
    break;
    case DLL_THREAD_ATTACH:
    MyThreadAttach();
    break;
    case DLL_THREAD_DETACH:
    MyThreadDetach();
    break;
    case DLL_PROCESS_DETACH:
    MyThreadDetach();
    MyProcessDetach();
    break;
    default:
    break;
    }
    }
    catch(std::exception& x) {
    std::cerr << x.what() << std::endl;
    return FALSE;
    }
    return FALSE;
    }

    where all the stuff in bold is just some garbage I've added trying to get it to print something, or crash or generate some failed load situation to show me that the function is getting called. It would certainly seem this function is never getting invoked. What the heck is going on? Again, do I need some project setting to identify this as an entry point function for the library? Matt

    C / C++ / MFC tools question

  • My DllMain is not getting invoked.
    M Matthew Busche

    I'm trying to use DllMain() to take care of some library/thread initialization and cleanup stuff, but no matter what I try I cannot get DllMain invoked for any of the four events for which it is supposed to be getting invoked! (I.e., process attach, thread attach, thread detach, process detach.) I found the following sentence in the MSDN description of DllMain():

    "DllMain is a placeholder for the library-defined function name. You must specify the actual name you use when you build your DLL. For more information, see the documentation included with your development tools."

    Is there some Dev Studio project setting I should be making to identify the name of my library entry point function? Another tidbit of information: I'm using simple load-time linking for my DLL. The MSDN DllMain description makes reference to LoadLibrary and FreeLibrary (functions you use for run-time dynamic linking). I sould be interested in hearing confirmation that DllMain IS compatible with simple load-time dynamic linking. Thanks much, Matt

    C / C++ / MFC tools question

  • might be a dumb question...
    M Matthew Busche

    That is my understanding. It is also my understanding that night will be followed by day in the coming hours. I could be mistaken about one or the other or both, but I'm fairly certain about both. Matt

    C / C++ / MFC question com

  • I want a function called on thread exit.
    M Matthew Busche

    Peter, OK, forget what I just wrote. If just found some words in the MSDN that would seem to imply that DllMain is used even if you use load time dynamic linking of the library. (Which I guess means that LoadLibrary must be invoked for you if you use load-time dynamic linking?) Let me know if I'm lost. Let me know if I'm not lost. I'm forging ahead. Matt

    C / C++ / MFC help question

  • I want a function called on thread exit.
    M Matthew Busche

    Peter, Thanks for your reply. I actually started to do this and only just now discovered that this only works for RUN-TIME dynamic-linking of a DLL. (I.e., where you use the LoadLibrary call just like you said.) I saw some sample code on how to use LoadLibrary and GetProcAddress to call a single simple function from a DLL, but I'm not exporting a single simple function, I'm exporting a handfull of C++ concrete and abstract classes (along with all their numerous member methods and overloaded operators). It is not clear to me how you'd use run-time linking for such a library. Supppose Peter, you inherited from one of my abstract base-classes, then when you wrote your constructor, how would you call my base class constructor that is exported from my DLL? And even if it's possible, my whole objective is to make my software as easy as possible to use. I certainly wouldn't want my users to have to jump through any flaming hoops to call a base class constructor or call the "=" operator for a class. Here's a thought. What if I had two libraries? Library ALPHA has all my user visible software and could be built arbitrarily for either dynamic or static linkage. If built as a DLL it would be expected to be used with load-time dynamic-linkage. DLL BETA has nothing in it but a DllMain. Now, here's the trick: suppose DLL ALPHA secretly does a LoadLibrary call on BETA via some singleton constructor found in ALPHA. This singleton is instantiated the first time a user of ALHPA references resources that require thread initialization and cleanup activities. Then, I would presume that every subsequent thread spawn and delete would cause this DllMain in BETA to be invoked, would it not? I presume also that DllMain in BETA could invoke methods defined in ALPHA (to effect thread initialization and cleanup.) I'm going to investigate this idea further and maybe try it out. Let me know if I misunderstood the implications of your email. I've been battling this silly problem for a week now. If I don't come up with a better solution soon, I'll have to simply publish a threadCleanup method that must be called by users of my library on thread exit, but I really don't want to have to do this. Once again, thanks sincerely for your help. Matt

    C / C++ / MFC help question

  • I want to export global data in a DLL
    M Matthew Busche

    KaЯl, Thanks very much for your sample code! I've got it working now. You never mentioned anything about dllimport! That was my problem. From my experimentation, I now believe the following:

    • For global data (certainly for built-in data types and I presume this goes for global C++ objects as well), the DLL source code module must declare the data using __declspec(dllexport), BUT the application module must declare the data using __declspec(dllimport). This seems a tad annoying since the header file must look different for the DLL compile and the Application compile.
    • For functions (and I presume this goes for class declarations as well), the DLL source code must likewise declare the function using __declspec(dllexport), BUT IN CONTRAST TO THE CASE FOR DATA the application can declare the function using __declspec(dllimport), __declspec(dllexport), or nothing at all!

    Actually I just found the dllimport/dllexport descriptions in the MSDN that would seem to support my claims, though I find it somewhat cryptic -- the kind of description that makes sense only after you already know what it's trying to describe. Maybe I'm just mentally slow or lazy. I will have to read the entire section a time or two to see what I can learn. Anyway, here is what I did for my source code to get this to work. ----- stupidDll.h ----- #ifndef STUPIDDLL_H #define STUPIDDLL_H #ifndef DllDecl #define DllDecl __declspec(dllimport) #endif int DllDecl getStupidInt(); extern DllDecl int x; #endif ------------------------- ----- stupidDll.cpp ----- #define DllDecl __declspec(dllexport) #include "stupidDll.h" int x = 8; int foo = 7; int getStupidInt() { return foo; } ------------------------- ----- stupidApp.cpp ----- #include "stupidDll.h" #include "stdio.h" int main(){ printf("%d %d\n", getStupidInt(), x); return 0; } ------------------------- As you can see, my DllDecl macro normally expands to __declspec(dllimport); however, I predefined the DllDecl macro in StupidDll.cpp before the #include "StupidDll.h" to force it to instead expand to __declspec(dllexport). Thanks again for your help. It was most helpful. Matt

    C / C++ / MFC c++ question

  • I want to export global data in a DLL
    M Matthew Busche

    Alexander, As I said in my email, I am trying to export two C++ objects -- not a simple integer. Do you still recommend a defs file? In addition, I have a few C++ base-class declarations and a few global C++ functions that I am also exporting. I would expect putting these in a defs file would not be as straight forward. Can you mix a defs file for data with __declspec for classes and functions all within the same DLL? Thanks much, Matt P.S., what is the significance of the superscript M. in your login?

    C / C++ / MFC c++ question

  • I want to export global data in a DLL
    M Matthew Busche

    KaЯl, Yes. Actually that was the first thing I tried. I get: stupidApp.obj : error LNK2001: unresolved external symbol "int x" (?x@@3HA) stupidAp/stupidApp.exe : fatal error LNK1120: 1 unresolved externals Error executing link.exe. And yes, in general I agree global variables (or in my case objects) suck, but if you knew what I was doing, I suspect you might forgive me. But I am not going to defend myself here. Never-the-less I appreciate your response and would be interested in any other ideas you may have. Thanks, Matt

    C / C++ / MFC c++ question

  • I want to export global data in a DLL
    M Matthew Busche

    I found these words in the MSDN: "Global variables in a DLL source code file are global to each process using the DLL." I know this to be true, because the following dll and app work for me: ----- stupidDll.h ----- #ifndef STUPIDDLL_H #define STUPIDDLL_H int __declspec(dllexport) getStupidInt(); #endif ------------------------- ----- stupidDll.cpp ----- #include "stupidDll.h" int x = 7; int getStupidInt() { return x; } ------------------------- ----- stupidApp.cpp ----- #include "stupidDll.h" #include "stdio.h int main() { printf("%d %d\n", getStupidInt()); return 0; } ------------------------- But say I don't want to have to call a function to get at the value of x. Shouldn't there be someway to export the symbol x in the DLL (just like I can export the symbol getStupidInt()) ? I.e., I want to be able to have something like: extern int x; in stupidDll.h so that applications can reference this global data directly. I presume I need some sort of __declspec on the above, but I haven't been able to figure it out yet. In case it matters, the data I want to export are a couple of C++ objects -- not simple ints. Thanks much, Matt Busche

    C / C++ / MFC c++ question

  • I want a function called on thread exit.
    M Matthew Busche

    Robert, I guess I'm not a big fan of polling. As for your second suggestion: I'm trying to write a library that other developers will use. My library won't be spawning threads -- the application written by someone else will. So to pursue your suggestion, I'd have to include in my library notes, "oh, and be sure to call MyCleanUpRoutine() before your thread exits. Don't really care for that either. I guess I'm going to have to figure out how to get a DLL to work for me instead. Actually, I think a DLL will work for me, but my initial attempts to create a DLL have not gone so well -- having problems getting global data from the DLL to link. :( Thanks much for your response. Matt Busche

    C / C++ / MFC help question
  • Login

  • Don't have an account? Register

  • Login or register to search.
  • First post
    Last post
0
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups