Exception in Fortran DLL after upgrading Visual Studio - c++

I have a C++ DLL. We developed it originally in Visual Studio 2005 and recently upgraded it to Visual Studio 2013. This DLL then calls into a Fortran DLL for some functionality (the Fortran DLL is provided by a third party developer who cannot share source code). Recently, for some inputs, the call to the Fortran library has started throwing an exception:
First-chance exception at 0x1C00BA50 in Application.exe: 0xC0000005: Access violation executing location 0x1C00BA50.
This exception only occurs when the Fortran DLL is called from the Visual Studio 2013 generated executable on Windows 7. When I call the same Fortran DLL with the same input from the Visual Studio 2005 executable, there is no exception and the Fortran DLL produces correct results. Additionally, running the Visual Studio 2005 solution on Windows XP SP3 does not produce an error either.
Supporting details:
The C++ DLL that calls the Fortran is a 32-bit, x86 DLL
Fortran DLL is built against DFort 6.1a
In dependency walker, needs: DFORRT.DLL, MSVCRT.DLL, and KERNEL32.DLL
The C++ executable is built for x86 using the "Visual Studio 2013 - Windows XP (v120_xp)" Platform Toolset
The crash does not happen on Windows XP SP3; it does on both 32 and 64-bit Windows 7 machines. I am setting up a Vista environment to test there, but won't have results for a few days.
If it helps, the function signature is:
extern "C"
{
typedef long (__stdcall *FUNCTIONID)
(
float* array1,
float* array2,
float* array3,
long& numItems,
long& numThings,
float* thingData,
float* thing2data,
float& result,
long* resArray,
float* resArray2,
float* resArray3);
}
The library is loaded by:
m_funcDLL = ::LoadLibrary("DLLNAME.DLL");
Additionally, we call this by:
FUNCTIONID pfnFUNC = nullptr;
pfnFUNC = (FUNCTIONID)GetProcAddress(m_funcDLL, "FUNCNAME");
if(pfnFUNC) {
try {
iErr = (*pfnFUNC)( args...);
}
}
The args are a mix of static arrays and dynamic arrays (although we have experimented with C++11's std::array and std::vector to pass things around; we get the same error using both container types).
We're not using Unicode on our builds (that's a wishlist item for now), so we're using Multibyte Character Sets (although none of the arrays passed in are char arrays).
The primary question I have is: Is anyone aware of any binary compatibility issues with Visual Studio 2013 on Windows 7 that would cause crashes like this? Are there things I should be looking at that I'm not?

DLLs and code using DLLs which are linked against different versions of the runtime library (and possibly other libraries) are in danger of breaking, if one or more of the following happens:
Interface to DLL uses classes/structures, where the size might differ depending on version of runtime library. (One unfortunate member might be enough).
Heap objects are not being allocated/freed at the same side of the interface.
Sometimes people play with compiler settings regarding alignment. Maybe different versions of compilers also change their "policy".
Look out for #pragma (pack,..), __declspec(align()) etc.
In older Versions of VS there were "single threaded" and "multi-threaded" versions of run time libraries. Mixing DLLs and Applications not linked against the same kind of library could cause trouble.
#include <seeminglyharmlessheader.h> in header files, seen by both application and DLL can hold some nasty surprises in stock.
Maybe an (unnoticed) change in other compiler/linker settings, e.g. regarding exception handling.
I could not fully follow the 32bit/64bit things you said in the question part. I don't think, mixing both works, but I also think you are not trying that.

Related

Is std::string header only in Visual Studio?

It looks like std::string is a header only file at Community/VC/Tools/MSVC/?/include/xstring, and all generated code should be included inside a build target.
If I'm correct, how does Microsoft guarantee that the next Visual Studio version doesn't change xstring and the std::string internal structure?
Update 1:
I got many downvotes for this question so let me explain why I decided to ask it.
I'm faced with strange crash, and I can not understand why this happen.
I use latest Qt 5.13.0 (MSVC2017_x64) and also I have some external libraries compiled with Visual Studio 2017. All have /MDd, I checked this with dumpbin util.
When I try to run any code that invokes Qt library and std::string, I'm getting wrong result (and crash at the end).
Here is very simple example:
#include <QApplication.h>
int main(int argc, char** argv) {
QString s1("Test");
std::string s2 = s1.toStdString(); // here we have s2 variable with wrong internal structure
return 0;
}
My idea was that QtCore DLL library has std::string with internal structure not compatible with std::string from Visual Studio 2017. But Qt was created with Visual Studio 2017 (maybe not same as my current Visual Studio, because there was several minor releases), so I decided to ask here if they are compatible or not.
Update 2:
Problem was in _ITERATOR_DEBUG_LEVEL. Looks like Qt was compiled with level 2 and all my external libraries and application were compiled with level 0.
This option affects internal structure of many C++ standard library classes and introduce such side effects. So when we are inside toStdString() and create std::string, we have level 2 and one internal structure. When we are in application code, we have level 0 and another internal structure. We assign object with one internal structure to object with another.
Anyway now I have better understanding of some internals.
how does Microsoft guarantee that the next Visual Studio version doesn't change xstring and the std::string internal structure?
Because they make a decision to guarantee that, or to not guarantee that.
For example, Visual Studio 2015 to 2019 are binary compatible.
That's a decision that was made, to do that. The result, if what you say is true, is that some of the implementation specifics of std::string on that platform are frozen. This is not unusual for libraries. libstdc++'s std::list::size was non-compliant to C++11 for many years, because they could not add a needed member variable without breaking binary compatibility.
In short, this is basically a project management decision, and if they ever change the header in a way that breaks things, they will tell you that binary compatibility has been broken and you need to rebuild and relink things accordingly.
As for your Qt issue, it does smell like a binary compatibility issue. But you say that both Qt and your application have been built in Visual Studio 2017 with /MDd, which would appear to rule that out. I would ask the Qt community for further help, possibly with slightly more information about your environment and about where you obtained Qt. Also ensure that you're using the version of Qt that's intended — perhaps there are multiple installations? Which one's on your include path?
Is std::string header only in Visual Studio?
Not entirely, it also depends on parts of the Standard C++ library that are implemented in Microsoft's Visual C++ Runtime. Building a binary with MSVC requires the VC++ runtimes to be linked. Only static libraries may be built without linking to a runtime, and then you must be careful to include none of the headers that require the runtime.
Is the std::string header only in Visual Studio?
(I originally read the headline this way.)
std::string is part of the C++ standard.
To use std::string on any platform that supports standard C++, you should use #include <string>. It is a standard header available with pretty much any C++ compiler.
Every compiler or platform may implement the standard in its own way though. For example with MSVC you can see that xstring is how Microsoft implements std::string under the hood. If you include xstring.h directly you are writing code that depends on the version of MSVC that provides that header. That code would not be portable to other compilers.
If I'm correct, how does Microsoft guarantee that the next Visual Studio version doesn't change xstring and the std::string internal structure?
Microsoft does not guarantee that the next Visual Studio version will have the same std::string internal structure. In the past the implementation of the standard library has changed with every VC++ runtime release, which is why Windows users end up having dozens of VC++ runtime versions installed in their Add/Remove programs list.
Thankfully Microsoft has given us a guarantee that Visual Studio 2015, 2017, and 2019 all use a binary-compatible C++ runtime. This means that binaries built using the standard library provided in Visual Studio 2015 are compatible with binaries built using 2017 and 2019 too. There is no guarantee (yet) that a future version of Visual Studio will not change the VC++ runtime implemenation again.

How to leave Visual Studio 2013 dlls dependencies behind?

My application when opened in others computer will give an error missing msvcr"something".dll, I found out that to fix this they need to install the following:
http://www.microsoft.com/en-us/download/details.aspx?id=40784
Which is Visual C++ Redistributable Packages for Visual Studio 2013.
I would like to compile the program with the dlls in the executable already, is such thing possible?
If not possible, where can I get all the dlls to put in the compiled project folder?
Try to set /MT for Release and /MTd for Debug in Project Settings->C/C++->Code Generation. This will make your program not dependent on Visual Studio libraries. But beware that all the libraries/ projects you will link with should also have the same option there, otherwise you'll get nasty linker errors.
You may also wish to select v120_xp in General->Platform Toolset for your program to be able to run on Windows XP
Because a lot of Programms use the functionality of these dll's they are dynamically linked.
So your filesize stays small and in case of fixes within the dll you dont have to recompile your program.
If you dont want this behaviour you can set in the projectsettings the dll's to "static linked" (/MT).
That way they will be compiled into your executable
Here is a relevant MSDN-article
Which is Visual C++ Redistributable Packages for Visual Studio 2013.
For Visual Studio 2013, you need:
http://www.microsoft.com/en-us/download/details.aspx?id=40784
If you were building with Visual Studio 2012, then you would need:
http://www.microsoft.com/en-us/download/details.aspx?id=30679
If you were building with Visual Studio 2012, then you would need:
http://www.microsoft.com/en-us/download/details.aspx?id=5555 (x86)
http://www.microsoft.com/en-us/download/details.aspx?id=14632 (x64)
The point is, you are probably going to need a runtime if you are writing portable C/C++ code by using functions like new, malloc, delete, free, etc.
You might be able to avoid the code if you use the Win32 API. For example, HeapAlloc and HeapFree, etc. Installers often use the Win32 API, and that's one of the reasons they usually don't need a runtime installed prior to running them.
I would like to compile the program with the DLLs in the executable already, is such thing possible?
Yes, its possible. Its called Static Linking (as opposed to Dynamic Linking).
But you will probably still need a runtime.
If not possible, where can I get all the DLLs to put in the compiled project folder?
Retired Ninja gave you this answer: Microsoft Visual Studio ~ C/C++ Runtime Library ~ Static/dynamic linking.
My application when opened in others computer will give an error missing msvcr "something".dll" ...
Another possible solution is to build your project with Visual Studio 2005 or Visual Studio 2008. The runtime used by VS2005 and VS2005 are usually available on Windows Vista, Windows 7, and Windows 8. So the computer may already have them.
But usually you just build your installer to carry around what you need. I use Inno Setup because it allows you to include both x86 and x64 components side-by-side. At install time, you just install the right components based on architecture (x86 vs x64), including the correct runtime. (At the time I choose Inno, Wix did not allow mixing architectures and I wanted a unified installer).

Omit the msvcr100.dll when developing in C/C++ for windows?

Is it possible to develop in C/C++ for windows and not to link against the msvcr100.dll?
I understand that this is the standard c library for windows, but I was wondering how all the programs on my computer could run if I hadn't Visual Studio or the Redistributable package installed?
Right-click your project in the Solution Explorer window, Properties, C/C++, Code Generation, Runtime Library setting. Change it to /MTd. Repeat for the Release configuration, pick /MT
You will now link the static version of the CRT, any functions you use get directly linked into your EXE instead of getting them from msvcr100.dll at runtime. So you no longer have the requirement to deploy the DLL along with your program.
Avoid using this option if you create your own DLLs. It then gets to be important that those DLLs and the EXE use the exact same CRT so they'll all share the same CRT state and the same heap. Because if they don't then you'll have nasty problems with passing C++ objects or pointers that need to be released from one chunk of code to another. An AccessViolation if you are lucky, a memory leak if you are not.
If you restrict your project to use only C programming language/library, then you can
only link against MSVCRT.lib which is completely baked in any Windows version since Windows XP SP3.
It means, that rather than dependency on MSVCR100.DLL (or any other Visual Studio DLL), you can only link against the standard C functions in MSVCRT. By the way, this technique is used in CoApp project developed under umbrella of Microsoft, so I'd consider it as a good pratice in such cases as yours.
Simply, download Windows DDK and link only against $(DDKInstallPath)lib\Crt\$(DDKPlatform)\msvcrt.lib
On Windows, I doubt it's possible to create a non-trivial program that doesn't use the CRT in some way.
It is possile to use the CRT without linking to msvcrXXX.dll -- simply link to the static libs instead. But to address your question:
how all the programs on my computer could run if I hadn't Visual
Studio or the Redistributable package installed?
If the programs on your PC were linked to msvcrtxxx.dll, then they couldn't. Sinmply, the redist that a particular program needed was already installed on your PC before you even came along, probably. Or at least, the parts of the redist needed by the program.

Delphi: Doesn't load a DLL unless I install Visual C++ 2008 Redistributable

I have a DLL that gets loaded in my application, like so:
procedure LoadTessDLL;
var
DLLHandle: THandle;
begin
DLLHandle := LoadLibrary(PChar(ExtractFilePath(application.exename) + 'tessdll.dll'));
if DLLHandle >= 32 then
begin
TessDLLLoaded := True;
We discovered that on an XP PC with Service Pack 2, the DLL fails to get loaded (the DLLHAndle = 0 etc), UNLESS we install Microsoft Visual C++ 2008 Redistributable. Then it gets loaded and works just fine.
Please can you help me get this working without it?
Do you control the source DLL? If not then no, the DLL relies on the C++ 2008 Runtime and it must be installed for the DLL to run and you need to add that as part of your install.
If you you do control the source for the DLL then statically link it to the C++ runtime, which will build the runtime into the DLL.
This issue has nothing to do with Windows XP. The DLL requires the C++ 2008 runtime on Vista and 7 as well, it just so happens that the machines you tested with already had it installed. The C++ runtime is not guaranteed to be installed on an any version of Windows.
If the DLL needs the VS2008 redistributable then it needs it and you should include the redistributable as part of your product's installer.
Microsoft provide the redistributable packaged up for inclusion in other installers and it is intended to be used in this way. (It'll add a megabyte or two to your installer.)
There is no getting around this unless you have the source to the DLL and can recompile it to statically link the C Runtime.
(Even if you do have the source, simply recompiling with static linking may introduce bugs. It's possible the DLL assumes it shares the same heap as some other module(s) in the process and that's only the case if they all dynamically link to the same C Runtime DLL. Well designed DLLs avoid such assumptions but you'd need to double-check the way the DLL is written to be sure.)
Well, my best guess would be that your TessDLL.DLL requires a DLL from the Visual C++ distributable. If it can't find the given DLL, it fails to load.
If I am right on this, the only way it will work without it is if you have the source code to TessDLL.DLL and remove all dependencies on Visual C++'s DLL.
A good place to start debugging this is on a station where it actually works. Make a little test program that load the DLL. Run it in the debugger and see what other DLL gets loaded when you load your DLL. If you're lucky, the probem could be in the version of an OS file that the MSVC redistributable happens to update.
Prior to installing Visual C++, I assume you have the DLL some place on your computer and installing VC puts another copy of the DLL possibly in your environment's PATH.
Have you tried putting the tessdll.dll in a location that is included in your search PATH? Say System32 or in the same directory from which you're running your executable? I'm not familiar with Delphi so I'm guessing at the logic of ExtractFilePath
"tessdll.dll". isn't that a DLL that's part of the Tesseract OCR software? The Windows version is compiled with Visual C++ 6 and thus it needs those runtime libraries. Your version seems to be compiled with VC++ 2008.
If you have the RAD Studio version then you could download the code and recompile it all with C++Builder, although that might need some adjustments. More information about the code also seems to be available here.
You have this options:
Compile the DLL without requiring the runtime, but be aware of issues if you have multiple DLLs written with VC++2008 requiring a shared runtime
Install the VC++ 2008 redistributable, which will install a system-wide available runtime
Install the needed VC+2008 runtime DLLs in the same path as the DLL requiring it, thus having a "private" copy of that.
See here: http://msdn.microsoft.com/en-us/library/zebw5zk9(VS.90).aspx

Can a C++ dll compiled using Visual Studio 2008 be used with Visual Studio 2005?

I'm going to be working with a C++ library written in plain C++ (not .NET and without MFC). The library is available compiled using both Visual Studio 2005 / Intel Fortran 9.1 and VS 2008 / Intel Fortran 10.1.
Obviously I'm going to grab the binaries for VS 2008 since that's the environment on my computer but I'm curious if there are reasons why a straight C++ library wouldn't be compatible between VS 2005 and 2008. I'd assume that the name-mangling would be the same but maybe there are other reasons. I haven't used C++ in a long time so I'm a little rusty when it comes to these things.
It should probably work. The DLL compiled with VS 2005 will be dependent on VS 2005's implementation of the C standard library (msvcr80.dll), whereas your code will depend on VS 2008's C library (msvcr90.dll). This means that at runtime, both versions of the C libraries will be loaded, which is ok, but it increases your memory usage and slows down your load time by a very small amount.
As the other posters have commented, you should be able to work in this way.
However, there is one issue that can be a big one - memory management. The C++ runtimes, in particular, can be tricky.
The biggest issue is that there are some incompatibilities between how the 2005 and 2008 runtimes manage memory. Everything works fine, provided you always allocate your memory in your VS2008 DLL, and always delete the memory allocated from within there within your DLL. This usually requires making some "extra" factory and cleanup methods in your DLL, and exposing these.
If you allocate memory from within your VS 2008 DLL, then delete it from code compiled using VS 2005, or vice versa, you may run into some very difficult to debug problems. It will often work, but have random crashes or instabilities.
The biggest issue you will run into is the usage of the CRT. If the CRT (C RunTime) is statically linked into the DLL, you shouldn't have any issues.
However if the CRT is dynamically linked into the project you may run into trouble. Visual Studio 2005 and 2008 use different versions of the CRT and they cannot easily be loaded togeter. But if one or both of the DLL's statically links the CRT you should be in decent shape.