Want to create DEF file, TDUMP and IMPDEF show mangled names - visual-c++

I have built Xerces-c_3_1.dll from source using the Visual Studio solution provided in the download package. It works with the sample applications that are part of that package (as long as they're built with VS).
But I need to use the DLL with apps developed in C++ Builder 10 Seattle. The incompatible linkage and COFF-vs-OMF format issues (import lib) mean I need to tweak the build instructions. I believe I need to change the calling convention in the project properties from __cdecl to __stdcall, and add a DEF file to translate the exported functions for my environment.
(I believe this because I wrote and support a DLL that is used by programmers writing in many languages. I do my development in C++ Builder [familiarity with the environment], and create the release version in VS Express 2015 [massive performance improvement over Embarcadero, I'm sorry to say]. Added a DEF file for just the 32-bit version [not needed for VC++ 64-bit, just to make me nuts], and it works for everybody.)
Running TDUMP.exe on my DLL gets me output that looks like this:
EXPORT ord:0060='Edit_RunEdits'
Running tdump -ee xerces-c_3_1.dll >tdump.txt on the Xerces-c_3_1.dll built using __cdecl gets output like this:
EXPORT ord:1763='?Initialize#XMLPlatformUtils#xercesc_3_1##SAXKKKQBD0QAVPanicHandler#2#QAVMemoryManager#2##Z'
EXPORT ord:1764='?Initialize#XMLPlatformUtils#xercesc_3_1##SAXQBD0QAVPanicHandler#2#QAVMemoryManager#2##Z'
Running impdef def.txt xerces-c_3_1.dll on the __cdecl build gets output like this:
?Initialize#XMLPlatformUtils#xercesc_3_1##SAXKKKQBD0QAVPanicHandler#2#QAVMemoryManager#2##Z #1763; ?Initialize#XMLPlatformUtils#xercesc_3_1##SAXKKKQBD0QAVPanicHandler#2#QAVMemoryManager#2##Z
Repeating TDUMP and IMPDEF on the __stdcall build gets similar results.
And this is expected.
But how can I create a DEF file from this noise? I would be perfectly happy with a sample of the format to use to turn "Initialize#XMLPlatformUtils" into something the linker can match to "XMLPlatformUtils::Initialize()" in my client app.
By the way, I also used IMPLIB on both versions (__cdecl and __stdcall) to create an import library, which I added to my test project, but the linker continues to issue "unresolved external" errors for my calls to XMLPlatformUtils::Initialize and XMLPlatformUtils::Terminate. I believe that should be expected because of the name mangling.

Related

Boost thread library version mismatch

I've created a managed C++ log parser application using C++ vectors and Winforms. I want to add multithreading and Boost seemed like a better option than Winforms BackgroundWorker because I want to be able to execute my existing C++ function with each thread. I installed Boost multiple times following multiple different tutorials (lastly this one: https://levelup.gitconnected.com/the-definite-guide-on-compiling-and-linking-boost-c-libraries-for-visual-studio-projects-c79464d7282d) and I still have the same issue when I try to #include <boost/thread.hpp>
Error LNK1104 cannot open file 'libboost_thread-vc143-mt-x64-1_78.lib'
I don't know why it's looking for this library when I have Boost 1_79 installed not 1_78. My .lib file also has "mt-gd-x64" not just "mt-x64". I've already specified the correct file path to the library in Project->Properties->Linker->General->Additional Library Directories. I've also tried installing Boost via Visual Studio 2022 NuGet Package Manager. The lib file in that folder is also slightly off. "vc120" instead of "vc143". I've even tried changing the .lib file name to match the file name in the linker error exactly but when I do that I get more errors like LNK1104 cannot open file 'libboost_chrono-vc143-mt-x64-1_78.lib'
Do I just need to delete all my Boost files and download version 1_78 and try again? Why is Visual Studio looking for the wrong file name when it compiles? Is my #include statement wrong?
I ended up solving this problem by downloading boost 1_78, building it, and specifying that folder instead or the 1_79 folder. If anyone might know why the program was looking for 1_78 instead of 1_79 feel free to respond Also big thanks to George Gkasdrogkas who wrote the tutorial that worked best for me on how to install Boost. Tutorial is linked in the question :)

how can I link a dll to fortran (visual studio)?

I have some DLLs that I want to use in a FORTRAN Project in VISUAL STUDIO but I can't find how.
Here is a simple code I'm using to find out how.
Using visual studio I created a DLL from this
subroutine printing
!DEC$ ATTRIBUTES DLLEXPORT::printing
print*,"dll naimi created"
end subroutine printing
I added the link of the DLL to project>properties>Linker>General>Additional Library directories
Main program:
program Console11
implicit none
call printing
end program Console11
ERROR : Error 1 error LNK2019: unresolved external symbol _PRINTING referenced in function _MAIN__.
other solutions related to this suggest using the .lib created while generating the DLL, but in my real case I only have the DLLs without their .lib.
So how to use a DLL ... ?
You appear to be trying to use a DLL as an input file to the linker.
(You also appear to be trying to specify a file for a linker option that takes a directory. To specify an additional input file for the linker, either add the file to the project just like you would attach a source file, or use the "Linker > Input > Additional dependencies" project property. The property you mention in your post then tells the linker where (which directories) to search for those additional dependencies.)
Unlike the unix convention, you do not link against DLLs when building executables and other DLLs on Windows. The DLL typically does not contain the necessary information for the linker - instead that information is contained in an import library (which is just a variation of a typical .lib static library) or equivalent.
If you were able to successfully build a DLL, then you will probably find the import library for that DLL in the same directory as the DLL. Supply that import library as an additional dependency for projects that require the DLL.
When you link an EXE or other DLL using an import library on Windows, the target DLL is automatically loaded by the operating system when your executable code is loaded. This is called load time dynamic linking.
If you do not have the import library for a DLL, then your choices are:
Ask the person who built the DLL for the import library.
Reference the DLL using run time dynamic linking, rather than load time. This means that you use the Windows API functions LoadLibrary, GetProcAddress and friends in your program to explicitly tell the operating system to load a particular DLL and to obtain the address of a function pointer. If you are using Intel Fortran, then complete examples of this are installed with the compiler - see in the file "C:\Program Files (x86)\IntelSWTools\samples_2016\en\compiler_f\psxe\DLL.zip" or similar.
Generate an import library from the minimum information in the DLL, plus other information about the DLL that you may have. One approach to this is to write a module definition file (.def) for the DLL, and then use the LIB utility to turn that def file into an import library. See How to make a .lib file when have a .dll file and a header file for an example.

Executable exporting symbols BUT not getting exported as they are unreferenced by the executable itself

I have a particular use case where executable needs to export certain symbols, which are imported and used by the dynamically loaded DLLs the executable loads on runtime.
The executable links with some static libraries, which actually have symbols that are exported while the DLLs use these static libraries headers to import those symbols.
If these symbols are not used or un-referenced in the executable, then the linker removes them and hence they do not get exported and hence not available for DLLs at load time.
This i solved on GCC / clang using --whole-archive and -force_load option respectively.
What about MSVC on windows? I use __declspec(dllexport) and __declspec(dllimport) for exporting and importing symbols on windows.
EDIT:
For code reference, you can find the code here: https://github.com/hunkabhicupid/exeexport
The issue is something similar to these posts 1, 2 BUT the answers to these posts did not help me find a solution or i did not find them useful.
Problem: On windows, STATIC LIB which contains an OBJ file that has a function marked __decl-spec(dll¬export) but if the same is not used in the EXE, function does not get exported from the EXE. On other platforms also we have the same problem BUT there we have compiler options like --whole-archive / -force_load, do make it work.
Links:
Link1
Link2
Only solution that come to my mind is to not create STATIC libs, rather include all code (static LIBS) in the executable then:
1. It works on Windows
2. It works on Linux without --whole-archive
3. It works on Mac OS X without -force_load
4. We also need not worry about if 2 & 3 include the dead code, exe bloat etc.
This is the only solution till the linkers become smart and throw out every unused symbol, except those marked specifically for external consumption i.e. marked to be exported.
Does dumpbin /exports {dll} show you the exports properly? Perhaps you should try dumpbin /exports {import lib}?
Based on the info so far I'm guessing the problem is not that the symbols are not exported but rather one of build order. If you get 'unresolved externals' when linking the dll, it seems you expect the exe-exported symbols to be resolved by the linker when linking the dll, but the exe is not built yet. (you probably wired it to reference the dll, so it builds only after the dll is linked).
One way to go about it is to have the dll LoadLibrary the exe and GetProcAddress the functions you want - but that really is a contrived way to achieve what you're after. If these symbols are defined in a static library, why not have both the exe and the dll link against it?

Visual Studio 2012 undocumented warning C4447

dllmain.cpp(16): warning C4447: 'main' signature found without threading mode
l. Consider using 'int main(Platform::Array<Platform::String^>^ args)'.
Above is a warning I got from building a Windows Store App DLL project. I didn't change anything in that default dllmain.cpp file except for including my own version of pch.
The documentation for this warning (along with many VS2012 errors/warnings) is nowhere to be found on MSDN and here is the only relevant link I can find:
http://social.msdn.microsoft.com/Forums/en-US/vssetup/thread/6daa9587-fe54-4e84-a8b9-0e5c52c2f6e8/
and the op there didn't get an answer.
If anyone knows what it means and how to fix it, it would be great!
As far as I can tell, you can safely ignore the warning. The compiler cribs when it sees a Win32-style DllMain being compiled using the /ZW flag (Consume Windows Runtime Extensions). However, the function gets called as you'd normally expect.
Alternatively, you can work around the warning by compiling dllmain.cpp without /ZW. You might need to adjust the PCH settings for this to properly work. This is the path taken by the DLL (Windows Store apps) C++/CX project template in Visual Studio.
Incidentally, the reason you do not get the warning when you're trying to build a Windows Runtime Component project (which builds everything using /ZW) is that a Windows Runtime Component doesn't declare a DllMain. This is not to say that it can't; it just picks up the dummy DllMain that the CRT defines (which basically turns off per-thread initialization and reports success).

CVTRES.exe is discarding my DLL exported functions

I'm working on a project that creates a DLL in C for Windows CE 5.0 using STANDARDSDK_500. The project is relatively simple with just one C source file. What I've noticed is that when I clean and build the project using Visual Studio 2005, it fails to create my Import lib. When I tell Visual Studio to rebuild it, it correctly creates the import lib.
Turning on verbose linking, I discover that in the failure case (clean and build) CVTRES.exe is discarding my functions, like so:
Invoking CVTRES.exe:
/machine:thumb
/verbose
/out:"C:\...\Temp\lnkC7E.tmp"
/readonly
/windowsce
".\standardsdk_500 (armv4i)\release\WLTBApi.res"
Microsoft (R) Windows Resource To Object Converter Version 8.00.50727.42
...
adding resource. type:VERSION, name:1, language:0x0409, flags:0x30, size:892
Discarded '.idata$4' from coredll.lib(COREDLL.dll)
...
Discarded WLRegisterStartupApp from WLTBApi.obj // my functions! Oh noes!
...
This discards all of my functions, which causes the linker to not create an import lib because there are no exported functions.
I figured that the input was the .res file mentioned in the commandline - WLTBApi.res. This file is identical in the intermediate directory after trying to compile both the working way (rebuild) and the non-working way (clean. build).
So, my first question is: what are the other inputs to the CVTRES.exe program so that I can find discrepencies between the two builds?
Second: what other troubleshooting techniques would you recommend?
Additional Info - I thought perhaps the .obj files were additional inputs - they differ between the builds. I now believe that they are outputs of CVTRES.exe. If anyone knows whether or not I'm correct in this, let me know.
Okay, so I found a solution, but I'm terribly dissatisfied with it. I discovered that the project I was building had a Dependency, but one that wasn't actually a dependency. In other words, the project, WLTBApi was building a DLL, and had a dependency configured, WLTBApiLib, but it wasn't actually using any of the output of that project. By removing the dependency, the problem went away.
I'd still love to know more about how to find an actual answer to what was going on, but maybe this answer will help someone else in the future.

Resources