Category: dll

How to embed .tlb as a resource file into .NET Assembly DLL?

We’re using our .NET Assembly DLL within native C++ through COM (CCW).
Whenever I make new version of my DLL, I have to send two files (.dll and corresponding .tlb) to crew that’s using it in their code.

Is it possible to embed .tlb file as a resource in .NET DLL file?

Comments:


It is not exactly straightforward to do this with Visual Studio .NET, but it can be done. At a basic level, what you have to do is this:

  1. Generate your TLB file, e.g., “YourLibrary.tlb”.

  2. Create a Win32 resource script file called, for example, “YourLibrary.rc” using a text editor (such as Notepad, or File/New/File…/Text File in Visual Studio).

  3. In the script file, type the following text verbatim (but substitute your actual TLB file name of course):

    1 typelib “YourLibrary.tlb”

  4. Save the script file to the same folder as the TLB file.

  5. From a Visual Studio Command Prompt, change to the folder with the script file and compile it using the following command:

    rc YourLibrary.rc

    This will generate a Win32 resource file in the same folder called “YourLibrary.res”.

  6. In Visual Studio, right click the project node (e.g., “YourLibrary”) in the Solution Explorer and select Properties.

  7. On the Application tab, under “Resources”, select the “Resource File” option and browse to the “YourLibrary.res” file from step 5.

  8. Save and rebuild the project.

The TLB will now be embedded as a resource in the DLL such that other COM applications can read it.

If you regenerate the TLB file later you will need to repeat step 5 to recompile the resource file, and step 8 to embed the new version in the DLL.

All that said, you may be able to automate some of this with Build Events or by putting custom MSBuild targets into your project file, but that is a whole other discussion.

Answers:

WinDbg symbol resolution

When using WinDbg, where should the private symbol files (pdb?) be placed?

My situation is: I have a DLL which I want to debug. I have the source code and symbol files for this DLL. This DLL is called by another DLL (which I don’t have symbols or source for) which, in turn, is called by an EXE (which I also don’t have symbols or source for).

My problem is that I am getting a warning that says

*** WARNING: Unable to verify checksum for C:TheProgramSomeSubfolderAnotherSubfolderMyDll.dll

This warning I think is the reason why I am getting the following type of messages in the call stack:

MyDll!AClass::AFunction+SomeHexAddress

My file structure looks something like this:

The exe: C:TheProgramprogram.exe

The calling dll: CTheProgramSomeSubfoldercaller.???

My DLL that I want to debug: C:TheProgramSomeSubfolderAnotherSubfolderMyDll.dll

Note: I set Symbol File path and the Source file path to where the debug DLL was generated, in my workspace on a different drive from the exe.. But I did copy the pdb + map files and put it on the dll that I wanted to debug..

Comments:


One option is to leave the symbol files where they are (i.e. in the build output folder) and then use -y WinDbg command line option to locate these files. Using this approach should guarantee that the symbol files are always be up to date.

From the Microsoft Help:

-y SymbolPath 
Specifies the symbol search path. Separate multiple paths with a 
semicolon (;). If the path contains spaces, it should be enclosed 
in quotation marks. For details, and for other ways to change this 
path, see Symbol Path. 

Answers:

It does not matter where you put private symbol files as long as you’re able to tell the debugger where they are.

The warning you’re seeing does not have any effect on the stack trace, but the fact you’re missing symbols for caller.DLL and app.EXE does.

Configuring symbols in windbg (locally) is as simple as using:

.sympath[+] path_to_pdbs
*and
.symfix+ path_to_system_pdb_store

You seeing:

MyDll!AClass::AFunction+SomeHexAddress

actually means nothing as long as SomeHexAddress is reasonable (and provided that MyDll.pdb has been found and loaded!) – it looks like a proper call stack entry.

Now, my question would be, what is the problem that you’re stuck with?

P.S. you don’t need .map file with windbg.

Answers:

As part of our build process, we copy the private PDB files and the released EXE/DLL files to a symbol server. At its simplest, this is just a UNC path, but you can configure it for access using HTTP.

To copy your output files, use the SYMSTORE.EXE program.

Then, configure your debugger (we use Visual Studio and WinDbg) to look in that path. For WinDbg, the simplest way to do this is to set an environment variable:

_NT_SYMBOL_PATH=
    SRV*C:WebSymbols*http://msdl.microsoft.com/download/symbols;
    \symsvrSymbols

(that should all be on one line)

This configures WinDbg to look on the Microsoft Symbol Server (caching the files in C:WebSymbols) and also to look in a local symbol store (\symsvrSymbols).

We also use the Source Server tools to store SVN details in the PDB file, meaning that we can get back to the exact source file used to build a particular release. Look in ...Debugging Tools for Windows (x86)srcsrv.

Answers:

Sorry for the late reply.
In your post you mention that you are seeing the following error message.

*** WARNING: Unable to verify checksum for C:TheProgramSomeSubfolderAnotherSubfolderMyDll.dll

You also ask the question, “where do I put my symbols for my DLL in the symbol path?”

Here is a response for the first problem:

Steps to identify mismatched symbols.

  1. !sym noisy
  2. .reload
  3. x MyDll!*class*
    *This reloads your dll, alternatively you can type kb to display the call stack of the DLL which should load it as well.

  4. !sym quiet
    *Reset’s back to original quiet symbol loading

Also you can run

0:001> lmv m myDll  *(and examine the Checksum)

Note: If you have a checksum, then Windbg can match the checksum of the DLL against the checksum of the PDB. Every development environment has a different way to generate a checksum.

Here is the response for the questions about where to put the PDBs

If you have MyDll.pdb added to a symbol store then you can use the following syntax

.sympath SRV*c:symcache*http://msdl.microsoft.com/download/symbols 

As Roger has suggested above…

However if you just have the PDB locally, you may want to put the path to the PDB first before going out to the symbol server like this

.sympath C:TheProgramSomeSubfolderAnotherSubfolder;SRV*c:symcache*http://msdl.microsoft.com/download/symbols

This way Windbg should look local to your SomSubFolder dir before trying to use the Symbols Server cache.

Thanks,
Aaron

Answers:

How to link a .DLL statically?

We have a (pure native C++) .DLL that is build by VS. As clients we have some native C++ applications and a .Net-Wrapper around this DLL written in C++/CLI. Finally there are some client applications for the .Net-Wrapper written in C#.

My problem is that the native.dll must be distributed in a different way than the .Net world works and the VS does not keeps track of that DLL.
So to let all my C# Apps work correctly I have to copy it to each executable directory or put it somwhere in %PATH% (which I would avoid on developer computers since they may want to start different apps with different versions of the DLL).
Even bigger problems occur if there are UserControls that reference the Wrapper-DLL: You have to copy the DLL to VS’s directory or again to %PATH%.
But the worst case occurs with our Translator tool. This tool keeps track of .Net-Assemblies and packs them into Translator-packages that can be send to an external translator. As far as I know there is no way to put the native .DLL into that package!

So I plan to link the native DLL statically into the .Net-Wrapper which would solve my problems.
But for our Native applications this native DLL must still be a DLL.

So I have two options:

  • Make two projects of that (one that generates a static library; and one that creates a dynamic one => I try to avoid this)
  • Find a solution to link DLLs statically
  • Find a way to let VS generate two outputs from one project

Comments:


Pick up a copy of DLL to Lib (Edit: If you can’t find a cheaper option)

Answers:

Another option is to have two projects, one project will output a .lib which can be statically linked, and a second project which will output a .dll and will have your .lib as dependency, you should add .def to your .dll with the symbols that you are planning to export, or else it will be empty.

Answers:

In the C++ project file for the dll, create two configurations, one that generates a DLL and one that generates a .lib. Two projects are not necessary, since any .NET/C++ project can support multiple build configurations (this is how Release and Debug versions build differently).

Answers:

You can generate a dll and export the entry point to a lib using dllexport, this is explained here

http://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx

Answers:

How do I use a third-party DLL file in Visual Studio C++?

I understand that I need to use LoadLibrary(). But what other steps do I need to take in order to use a third-party DLL file?

I simply jumped into C++ and this is the only part that I do not get (as a Java programmer). I am just looking into how I can use a Qt Library and tesseract-ocr, yet the process makes no sense to me and is so difficult to google.

How do I tell the compiler of the functions that I am using? Should there be an include file from the third-party vendor?

Comments:


These are two ways of using a DLL file in Windows:

  1. There is a stub library (.lib) with associated header files. When you link your executable with the lib-file it will automatically load the DLL file when starting the program.

  2. Loading the DLL manually. This is typically what you want to do if you are developing a plugin system where there are many DLL files implementing a common interface. Check out the documentation for LoadLibrary and GetProcAddress for more information on this.

For Qt I would suspect there are headers and a static library available that you can include and link in your project.

Answers:

I’f you’re suppsed to be able to use it, then 3rd-party library should have a *.lib file as well as a *.dll file. You simply need to add the *.lib to the list of input file in your project’s ‘Linker’ options.

This *.lib file isn’t necessarily a ‘static’ library (which contains code): instead a *.lib can be just a file that links your executable to the DLL.

Answers:

You only need to use LoadLibrary if you want to late bind and only resolve the imported functions at runtime. The easiest way to use a third party dll is to link against a .lib.


In reply to your edit:

Yes, the third party API should consist of a dll and/or a lib that contain the implementation and header files that declares the required types. You need to know the type definitions whichever method you use – for LoadLibrary you’ll need to define function pointers, so you could just as easily write your own header file instead. Basically, you only need to use LoadLibrary if you want late binding. One valid reason for this would be if you aren’t sure if the dll will be available on the target PC.

Answers:

In order to use Qt with dynamic linking you have to specify the lib files (usually qtmaind.lib, QtCored4.lib and QtGuid4.lib for the “Debug” configration) in
Properties » Linker » Input » Additional Dependencies.

You also have to specify the path where the libs are, namely in
Properties » Linker » General » Additional Library Directories.

And you need to make the corresponding .dlls are accessible at runtime, by either storing them in the same folder as your .exe or in a folder that is on your path.

Answers:

As everyone else says, LoadLibrary is the hard way to do it, and is hardly ever necessary.

The DLL should have come with a .lib file for linking, and one or more header files to #include into your sources. The header files will define the classes and function prototypes that you can use from the DLL. You will need this even if you use LoadLibrary.

To link with the library, you might have to add the .lib file to the project configuration under Linker/Input/Additional Dependencies.

Answers:

To incorporate third-party DLLs into my VS 2008 C++ project I did the following (you should be able to translate into 2010, 2012 etc.)…

I put the header files in my solution with my other header files, made changes to my code to call the DLLs’ functions (otherwise why would we do all this?). :^) Then I changed the build to link the LIB code into my EXE, to copy the DLLs into place, and to clean them up when I did a ‘clean’ – I explain these changes below.

Suppose you have 2 third-party DLLs, A.DLL and B.DLL, and you have a stub LIB file for each (A.LIB and B.LIB) and header files (A.H and B.H).

  • Create a “lib” directory under your solution directory, e.g. using Windows Explorer.
  • Copy your third-party .LIB and .DLL files into this directory

(You’ll have to make the next set of changes once for each source build target that you use (Debug, Release).)

  1. Make your EXE dependent on the LIB files

    • Go to Configuration Properties -> Linker -> Input -> Additional Dependencies, and list your .LIB files there one at a time, separated by spaces: A.LIB B.LIB
    • Go to Configuration Properties -> General -> Additional Library Directories, and add your “lib” directory to any you have there already. Entries are separated by semicolons. For example, if you already had $(SolutionDir)fodder there, you change it to $(SolutionDir)fodder;$(SolutionDir)lib to add “lib”.
  2. Force the DLLs to get copied to the output directory

    • Go to Configuration Properties -> Build Events -> Post-Build Event
    • Put the following in for Command Line (for the switch meanings, see “XCOPY /?” in a DOS window):

    XCOPY "$(SolutionDir)"lib*.DLL "$(TargetDir)" /D /K /Y

    • You can put something like this for Description:

    Copy DLLs to Target Directory

    • Excluded From Build should be No.
      Click OK.
  3. Tell VS to clean up the DLLs when it cleans up an output folder:

    • Go to Configuration Properties -> General -> Extensions to Delete on Clean, and click on “…”; add *.dll to the end of the list and click OK.

Answers: