What exactly is the "Multi-threaded Debug DLL" Runtime Library option doing in VS 2008? - vb.net

I have a solution in VS 2008 that creates a DLL. I then use that DLL in another application. If I go in to the DLL projects property pages and change the following configuration for a DEBUG build then the built dll no long provides the desired functionality. If I change it back and rebuild the DLL, then the DLL does provide the correct functionality:
Property Pages => Configuration Properties => C/C++ => Code Generation => Runtime Library
If set to "Multi-threaded Debug DLL (/MDd)"
then everything works as it should. I get the correct functionality from the DLL
If set to "Multi-threaded DLL (/MD)" then the DLL does not function properly...no runtime errors or anything, it just doesn't work (The DLL is supposed to plot some lines on a map but does not in this mode).
So the question is, why does using the /MDd flag result in correction functionality of the underlying code, while /MD results in incorrect functionality?
A little background...somebody else developed the DLL in C++ and I am using this DLL in a VB.net application.

All DLL's/debug code generation must match across everything that uses them. There may be another referenced library or object or dll or some code in there that is built using the wrong options; or specific options for an individual element that override the global project options.
The only way of figuring it out is to meticulously check all of the options for each file, checking the included and referenced libraries (.lib and .dll) and object files. Check the linker options too.
The reason why it doesn't work is probably because the debug version adds extra guard blocks around memory to allow detection of errors.

I had similar problems. My application which "used" a 3rd party DLL crashed when its runtime library was set to "Multi-threaded DLL (/MD)", but worked when its runtime library was set to "Multi-threaded Debug DLL (/MDd)".
It has something to do with passing std::strings and std::lists across the DLL interface.
Our guess was the low level definition of these types was somehow different in the two runtime libraries.
We solved our related problems using this rule...
The DLL and the DLL user must be build using the exact same runtime library.

The main difference between the two options is in the libraries that your code will be linked at later. for the debug version for example this will include LIBCMTD.LIB and a few others. if your library is going to be built as debug the you should always link with MDd. failing to do so will result in lots of unresolved external linker errors at best. and sometimes the code compiles normally but crashes at runtime. if this happens in vb.net then a catch can easily hide the error. I guess you should make sure you build setting is correct. for more detailed information check this.

Related

Dynamically linked DLL is loaded immediately after starting the application

I've dynamically linked libhunspell.dll (HunSpell) to my application. It works, but there is a dumb problem which I don't know why it happens.
Even before I use LoadLibrary("path\\to\\libhunspell.dll"); to load it and use it, on the start of the application it attempts to load the library by itself. If I place the libhunspell.dll into the path where my main executable resides, it can load it, otherwise it reports an error, immediately after starting the application - This application has failed to start because LIBHUNSPELL.DLL was not found. Re-installing the application may fix this problem. and the application doesn't start.
I would understand if the LoadLibrary would use invalid path but this happens as soon as the executable runs, even before the first statement in WINAPI _tWinMain(HINSTANCE, HINSTANCE, LPTSTR, int) executes (I've tried to place a breakpoint and it doesn't even reach it, so this happens before).
So, as a result, I must place libhunspell.dll in the same folder as my application executable, and not in the path I want.
This is probably easy to fix although I don't what to look for.
So the question is - how do I avoid it loading it immediately and have it wait until I use LoadLibrary call?
Here is how I linked if it can help:
1) compiled libhunspell.dll in Visual Studio 2015 (I used /MT option to link it statically so it doesn't have VC++ Redistributable as a dependency).
2) created import library (libhunspell.lib) using implib.exe -a -c -f libhunspell.lib libhunspell.dll
3) linked that to the source .cpp unit which is using it using #pragma comment(lib, "libhunspell.lib") (it is RAD Studio 2010 so the .lib is required unlike newer versions).
4) later in the same .cpp used LoadLibrary to load this library and used it.
By linking in the import stubs (libhunspell.lib) the OS will load the DLL for you as it is now a static dependency.
One approach would be specify the library as a delayload dependency: /DELAYLOAD:libhunspell.lib via the linker options. You can then call LoadLibrary on the DLL.
The only other option is to stop including the .lib in the linker step, making it truly a dynamic dependency.
I assume you did Add to project a *.lib file for your DLL. That is a kind of "static" linkage done in the App initialization (prior to your forms are created). So it has two disadvantages.
You DLL must be in the same path as the Apps EXE file
Sometimes DLL file name is locked (can not be changed)
The advantage is that you do not need to do any coding for the DLL loading as the VCL do it for you ... so your app should not contain the LoadLibrary,GetProcAddress calls you just include the *.h file with propper import declarations ...
For dynamic linkage you need to remove the *.lib from your project and use WinAPI LoadLibrary + GetProcAddress for loading your DLL as josh poley suggested. Here an example:
Builder C++ calling VC++ class
Beware there was/(is?) a bug in the GetProcAddress preventing from loading all the functions from your DLL in some cases. Especially if the DLL has old legacy mangling of names the count of functions is high and the DLL was created on compiler incompatible with the mangling in question.

Getting out of DLL Hell with Microsoft.VC90.CRT?

I've built a inproc com server dll which I can package as 1 file or many via the build utility py2exe. When I allow all the dependencies to remain external, I have no issues, but bundling as 1 file produces problems.
When the dll is utilized (either registering it or instantiating a com object from it), it immediately loads MSVCR90.DLL from the path c:\windows\winsxs\x86_microsoft.vc90.crt_1fc8b3b9a1e18e3b_9.0.30729.6871_none_50944e7cbcb706e5\MSVCR90.DLL no matter what I do, I can't change that. There is no information that I can find (using Dependency Walker) to indicate what is causing that to load. It just happens magically...
Then, later on it loads that dll again via an explicit call to LoadLibraryA("MSVCR90.dll") (part of some py2exe black box?), but this time it does not look into the winsxs manifests / directory. Instead it looks to the system path and/or will respect a dll redirection. That's when the problem occurs. If I set the system path to start with c:\windows\winsxs\x86_microsoft.vc90.crt...\ it will load the exact same dll and be happy - but if ANY other file is utilized - inclusive of a copy of the EXACT same dll - but at a different path - then the whole thing blows up. It can't handle using two different files.
How can I fix this? Ideally, I've love to make the initial magic loading of the dll draw upon a private assembly, but no matter what I do with manifests or .dll.local etc it will not respect that until this second dll loading takes place.
Note that with the non-bundled dll (external dependencies) it always uses the winsxs MSVCR90.DLL.
I can "fix" my failure to use the dll by forcing the system path to load the winsxs copy, but that is pretty useless for a deployable com server!
The reason is that you DLL has a manifest that tells the module loader to search also in the SxS storage.
You have several choices
Build your DLL using static linkage. Not using any of the MFC-DLLs (see project settings)
Don't use a side by side manifest for the DLL and still use the MFC DLLs. But beware you have to ship those DLL with your DLL in the local path (see DLL search sequence docs)
Use a later build of VS. Later versions of VS don't use the SxS storage any more and there are no manifests for those DLLs any more.
For the 2. see this article in code project. There is an update for VS-2008 [here].
2
Build your DLL

How to use ZeroBrane Studio IDE debugger when lua is compiled as c++

I have compiled Lua 5.3 as a 32 bit c++ DLL and exe. The DLL contains all the lua code except for lua.cpp and luac.cpp. The exe compiles lua.cpp and uses the DLL to run the lua interpreter. This works fine when running on its own from the command line. I wish to be able to run from the IDE using this DLL and exe.
If I replace /ZeroBraneStudio/bin/lua53.dll and lua53.exe with my own versions, I can run scripts (clicking the two green arrows). However, debugging does not work, giving the following error:
The procedure entry point luaL_addlstring could not be located in the dynamic link library lua53.dll.
I can see that this is happening because the debugger is making use of luasocket. \ZeroBraneStudio\bin\clibs53\socket\core.dll is dependent on lua53.dll, and is expecting it to contain lua compiled as c.
So, what is the correct solution to this - is it to compile luasocket as c++ as well?
(And, if so, does anybody have instructions/guidance for doing so? I have been unable to find anything on this.)
Thanks.
I'm not sure how exactly the DLL was compiled, but the error message likely indicates that the luaL_addlstring and other functions are not exported by it. If the symbols are exported correctly, you should be able to load luasocket and get the debugging working. See this thread for the related discussion.
Also, you don't need to replace lua53 library and executable, as you can configure the IDE to use your own copy of it using path.lua53 configuration setting as described in the documentation.
Okay, I was able to get it working. The solution was to compile luasocket as c++. I won't give full instructions on how to do this here, but some points to hopefully help anybody else with the same issue:
Got luasocket from here: https://github.com/diegonehab/luasocket
Renamed all *.c files to *.cpp
Renamed Lua52.props to Lua.props (I am using lua 5.3 but seems like it is compatible?)
Placed lua headers and lib in appropriate folders
Opened solution in Visual Studio 2012
Fixed up minor issues with project files, like the renaming of the files.
Added 'extern "C"' to declaration of luaopen_socket_core and luaopen_mime_core functions (necessary for lua to be able to load libraries).
Built solution
Copied new dlls into clibs53/socket and clibs53/mime folders.
I used Dependency Walker to help with this. If anybody wants further details in the future please leave a comment.

How do I get TFS teambuild to build c#>VB6>c# application (ComReference prob?)

I'm trying to get TFS team-build to reliably build a WPF C# app. This app relies on a VB6Lib.dll which we maintain, this VB6Lib.dll itself relies on other C# libs that we also maintain.
I've set up a build definition to build (in order):
VbDependencies.sln (all libs in this have com interop set, thus the VB6 can find their TLBs)
buildVB6Lib.proj (an msbuild file which calls "VB6.exe /make /d" to make the VBLib.dll on the build server, as part of this script I've been copying the VB6Lib.dll output to C:\tmp)
MainApp.sln (in my workspace, I've added a reference to C:\tmp\VB6Lib.dll)
Does this sound ok
?
On my dev laptop I usually build the VB6, copy its output to \tmp and then regsvr32 it there before adding a reference to it in my C# solution. It's this step that I'm not convinced my build def is doing.
Also, is there a way to get more useful output from the VB6 build, currently I get "Compile Error in File 'xxx.bas' Can' find project of library", but not which actual library it can't find.
You are correct in that the critical point in your build process on the development system lies in registering the COM object. However, one does not in general want to register the COM object on the build server, as this can cause all kinds of versioning issues and silent failures when the wrong COM object is registered or the registration fails.
The proper way to accomplish this is to generate an interop assembly manually and reference that instead of the COM object. This is accomplished with the tlbimp utility, for instance:
tlbimp ..\Libraries\VBLib.dll /out:..\Libraries\Interop.VBLib.dll
Run that command on your development system, then remove the reference to VB6Lib.dll and add a reference to Interop.VBLib.dll. You can then add the tlbimp command as a prebuild event in the referencing project so that the interop assembly is always build from the correct version, and you will never again need to have your COM object registered on the build system.

How do I fix fatal error C1113: #using failed on 'Mylib.lib'

I have a project which uses C++/CLI to implement a GUI and some background processing to talk to a sensor. I've got that all working and a lot of the comms stuff which we use to communicate the the sensor sits in a .dll. The problem is that I'd like to combine the library into the main executable to avoid having to worry about distributing .dlls.
I've got a demo project which works fine using a .lib but when I try and switch the mani code body to produce a .lib instead of .dll I get the following error:
1>------ Build started: Project: MyTool, Configuration: Debug Win32 ------
1>Compiling...
1>stdafx.cpp
1>.\stdafx.cpp : fatal error C1113: #using failed on 'c:\projects\MyTool\debug\MyLib.lib'
A bit of googling suggests this happens when you've not got the MSIL switch applied, but it's definitely in there in the library project.
I have a mixture of managed and unmanaged code in both my demo project and the real thing so I'm really struggling to see what the problem is here.
Any suggestions would be very gratefully received!
I am guessing a bit, but I suspect the "MyTool" project has the "MyLib" project as one of its "references" ("Project" menu >> Properties >> Common Properties >> References).
When you change the type of the MyLib project to a LIB instead of a DLL, you need to remove "MyLib" from the project references. You then update the project dependencies of the solution ("Project" menu >> "Project Dependencies...") so that MyTool depends on MyLib.
If you are linking to a mixed mode (managed/native) DLL you may get this error. Which you shouldn't if the project uses CLR even if one of the source files doesn't. But anyway, if that is the case, then try removing the reference from Project|Properties|Common Properties|References and then re-adding it.
I also ran into this. The reason it was failing was because I was compiling my native/managed C++ DLL to target .NET 4.0. And the DLL I was #using was a .NET 2.0 DLL. As such it was failing, even though the paths and file names lined up perfectly. In this case the error message was absolutely of no help at all.
I solve it by updating the independent DLL to .NET 4.0. So that both assemblies were using the same .NET framework.