Thread: Error calling DLL from protected location

  1. #1

    Join Date
    May 2005
    Posts
    1,042

    Error calling DLL from protected location

    Hi all,

    I'm working on a wave analysis project where an option allows the program to call a user defined function, stored in a DLL, to apply user-defined forces at each time step in a simulation. The code works on XP but not Windows 7. As such, I believe the issue relates to permissions and protection - a systems level topic I have no clue how to circumvent.

    I am running from an Administrator account, and also tried running the main program with the 'Run As Administrator' option.

    I know the DLL is not being called because I have a message box popup, allowing me time to attach the debugger to the process.

    What's most perplexing is that, in one instance, it magically worked, and I have no idea why.

    The main simulation program is in "Program Files", with the user dll assumed to be in the same location as the program executable.

    Any insight into the nature of this problem would be greatly appreciated.

    EDIT:
    Looks like I posted in C++ not Windows
    I'm not immature, I'm refined in the opposite direction.

  2. #2
    Registered User
    Join Date
    May 2011
    Location
    Around 8.3 light-minutes from the Sun
    Posts
    1,949
    When you ported the program over to Windows 7 did you recompile everything to make it 64bit? There was a bug floating around MSDN wrt Windows 7 and calling 32 bit dlls. The bug resulted in an error however, I think it was "invalid image file" or something like that.
    Quote Originally Posted by anduril462 View Post
    Now, please, for the love of all things good and holy, think about what you're doing! Don't just run around willy-nilly, coding like a drunk two-year-old....
    Quote Originally Posted by quzah View Post
    ..... Just don't be surprised when I say you aren't using standard C anymore, and as such,are off in your own little universe that I will completely disregard.
    Warning: Some or all of my posted code may be non-standard and as such should not be used and in no case looked at.

  3. #3

    Join Date
    May 2005
    Posts
    1,042
    Hi Andrew,

    I did recompile to 64 bit, but was unaware of that bug so thanks for the info. I'll have to research that.
    I'm not immature, I'm refined in the opposite direction.

  4. #4
    the hat of redundancy hat nvoigt's Avatar
    Join Date
    Aug 2001
    Location
    Hannover, Germany
    Posts
    3,130
    Do you get any error message or crashed? How is the dll linked to your program? Do you load it dynamically, if so, was it found and was the entry point found?

    Did you recompile the executable with a newer compiler when changing systems? The STL and most other libraries can't be mixed, all executables and libraries need to be compiled by the same compiler (including version) to function.
    hth
    -nv

    She was so Blonde, she spent 20 minutes looking at the orange juice can because it said "Concentrate."

    When in doubt, read the FAQ.
    Then ask a smart question.

  5. #5
    Registered User
    Join Date
    May 2011
    Location
    Around 8.3 light-minutes from the Sun
    Posts
    1,949
    Here is a similar thread I came across when trying to find the MSDN report: Unmanaged DLL - Win64. It may provide a good starting point for you.
    Quote Originally Posted by anduril462 View Post
    Now, please, for the love of all things good and holy, think about what you're doing! Don't just run around willy-nilly, coding like a drunk two-year-old....
    Quote Originally Posted by quzah View Post
    ..... Just don't be surprised when I say you aren't using standard C anymore, and as such,are off in your own little universe that I will completely disregard.
    Warning: Some or all of my posted code may be non-standard and as such should not be used and in no case looked at.

  6. #6
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by BobMcGee123 View Post
    Hi Andrew,

    I did recompile to 64 bit, but was unaware of that bug so thanks for the info. I'll have to research that.
    It's not a "bug" it's a rule... a 64bit executable cannot load a 32 bit dll... a 32 bit executable cannot load a 64 bit dll. This is because of difference in the size of pointers and addresses also note that a number of commonly used data types need to be adjusted as well... for example when using unsigned ints to store pointers you need to change all UINT references to UINT_PTR... Programming Guide for 64-bit Windows (Windows)

    If your dll is 32 bits... you have two choices... either recompile it to 64bits or rebuild your executable as 32 bits.

    Also note that you must adjust manifests in both executable and dll accordingly...

    32 bit manifest...
    Code:
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
      <assemblyIdentity type="win32"
                        name="AutoLogon"
                        version="1.0.0.0"
                        processorArchitecture="X86" />
      <description>
        Auto logon tool
      </description>
      <dependency>
        <dependentAssembly>
          <assemblyIdentity type="win32"
                            name="Microsoft.Windows.Common-Controls"
                            version="6.0.0.0"
                            processorArchitecture="X86"
                            publicKeyToken="6595b64144ccf1df"
                            language="*" />
        </dependentAssembly>
      </dependency>
      <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
        <security>
          <requestedPrivileges>
            <requestedExecutionLevel  level="asInvoker" 
                                      uiAccess="false" /> 
          </requestedPrivileges>
        </security>
      </trustInfo>
    </assembly>
    64 bit manifest...
    Code:
    <?xml version="1.0" encoding="UTF-8" standalone="yes"?>
    <assembly xmlns="urn:schemas-microsoft-com:asm.v1" manifestVersion="1.0">
      <assemblyIdentity type="win32"
                        name="AutoLogon"
                        version="1.0.0.0"
                        processorArchitecture="amd64" />
      <description>
        Auto logon tool
      </description>
      <dependency>
        <dependentAssembly>
          <assemblyIdentity type="win32"
                            name="Microsoft.Windows.Common-Controls"
                            version="6.0.0.0"
                            processorArchitecture="amd64"
                            publicKeyToken="6595b64144ccf1df"
                            language="*" />
        </dependentAssembly>
      </dependency>
      <trustInfo xmlns="urn:schemas-microsoft-com:asm.v3">
        <security>
          <requestedPrivileges>
            <requestedExecutionLevel  level="asInvoker" 
                                      uiAccess="false" /> 
          </requestedPrivileges>
        </security>
      </trustInfo>
    </assembly>
    Last edited by CommonTater; 09-09-2011 at 10:03 AM.

  7. #7
    Banned
    Join Date
    Aug 2010
    Location
    Ontario Canada
    Posts
    9,547
    Quote Originally Posted by nvoigt View Post
    Do you get any error message or crashed? How is the dll linked to your program? Do you load it dynamically, if so, was it found and was the entry point found?

    Did you recompile the executable with a newer compiler when changing systems? The STL and most other libraries can't be mixed, all executables and libraries need to be compiled by the same compiler (including version) to function.
    So much for C++'s claims of portability....

  8. #8

    Join Date
    May 2005
    Posts
    1,042
    Hi nvoigt, thanks for the reply. I'm actually being steered in a different direction, a support engineer told me I ought to be using Fortran, but is unsure of why the C++ version works on XP and not Win7.

    Do you get any error message or crashed? How is the dll linked to your program? Do you load it dynamically, if so, was it found and was the entry point found?
    I think I need to clarify the nature of my setup. I'm using a third-party simulation tool that, upon execution of a time domain simulation, calls a function called "user_force" compiled to a DLL.

    The simulator does not crash on Windows 7, it simply fails to call the function stored in the DLL. I'm not sure how the program is loading the DLL. The symbols are decorated with the STDCALL mechanism (so, while it's a C++ project, I'm really writing C with "extern" applied to the exported symbols. This is a requirement of the simulator, whose kernel was written in Fortran a bazillion years ago but has to interface with newer languages).

    I ported the code to Fortran 90 and am getting new funny behavior (which also makes this posted invalid as this is a C++ forum). A call to the DLL is made in three places: at initial startup, during each time step of the simulator, and at simulator shut down. On the initial call I create a message box, freezing simulator execution if I want to attach a debugger. At each time step I write a debug message to a console window (provided by the simulator), and another such message at simulator shut down. Similar to the C project, it works exactly as expected in XP. What's different is that the Fortran version of the code, when executed on Windows 7, actually prints the debug message at shut down, but nowhere else!

    I did rebuild the code on each machine, 32bit for the XP machine, 64bit for the Windows 7.

    Here is a similar thread I came across when trying to find the MSDN report: Unmanaged DLL - Win64. It may provide a good starting point for you.
    Thanks for the link Andrew.

    I've got a 32bit Win7 partition that I might try, but for the time being I'm just going to continue on the XP machine where the damn thing works, lol
    Last edited by BobMcGee123; 09-09-2011 at 10:35 AM.
    I'm not immature, I'm refined in the opposite direction.

  9. #9
    'Allo, 'Allo, Allo
    Join Date
    Apr 2008
    Posts
    639
    What's the error returned by GetLastError when you fail to LoadLibrary or GetProcAddress? If you don't have control of the loading code, grab Process Monitor to see what it's trying to load and the error, or grab DebugView and wade through the loader's debug spew.

  10. #10
    Officially An Architect brewbuck's Avatar
    Join Date
    Mar 2007
    Location
    Portland, OR
    Posts
    7,396
    Sounds to me like there's a bug in the app or the DLL. Thus explaining both "it changes when moving to another platform" and "at least once, it magically worked." I seriously doubt this has anything to do with DLLs, loading of DLLs, administrator permissions, or OS version. Just a bug somewhere.
    Code:
    //try
    //{
    	if (a) do { f( b); } while(1);
    	else   do { f(!b); } while(1);
    //}

  11. #11
    Registered User VirtualAce's Avatar
    Join Date
    Aug 2001
    Posts
    9,607
    So much for C++'s claims of portability....
    It has nothing to do with portability and everything to do with where the template inline expansion occurs. If you export a std::string and/or use it as a parameter to an interface method in a DLL and the client code and the DLL code were compiled with different versions of the STL it is highly likely that when the std::string is used in the DLL it will crash the program b/c the version in the client code and the DLL do not match. I have experienced this exact problem first hand. There is a hack fix for std::string since you can pass in const char * to any function requiring std::string and it will be implicitly converted to std::string. The conversion will happen in the DLL and everything works as expected.
    Luckily if you attempt to do this and compile with at least warning level 3 you will get warning C4251 stating 'class <name> needs to have a dll interface to be used by clients of class <name>'

    This same rule applies to any templates being exported from DLLs and is not only applicable to STL templates and containers.

    The quick solution of course is to use the PIMPL idiom and export the PIMPL instead of the implementation. A better approach than that which eliminates the export altogether is to create a factory method that factories out the object in question and a method that can also clean up said object in the DLL. Using this method does not require clients to link with the export library of the DLL.
    Last edited by VirtualAce; 09-09-2011 at 10:01 PM.

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. error C2248: can not access protected member
    By r0flc0pter in forum C++ Programming
    Replies: 3
    Last Post: 08-19-2009, 10:34 AM
  2. Replies: 1
    Last Post: 08-13-2008, 02:51 AM
  3. calling functions and error messages
    By l2u in forum C++ Programming
    Replies: 9
    Last Post: 07-27-2008, 01:06 PM
  4. error in calling a function
    By arian in forum C++ Programming
    Replies: 3
    Last Post: 12-24-2003, 02:42 AM
  5. error calling function
    By simhap in forum C++ Programming
    Replies: 3
    Last Post: 11-29-2001, 07:58 PM