CodeSteps

Python, C, C++, C#, PowerShell, Android, Visual C++, Java ...

Visual C++: Exporting functions from a DLL using “.DEF” file.

As we discussed in our previous article, the functions in the DLL can export using the “__declspec(dllexport)” keyword or “.DEF” file. We have already discussed exporting the functions using the “__declspec(dllexport)” keyword in our previous article. In this article I am going to discuss exporting functions in the DLL using “.DEF” file.

Let’s start this article with a simple “C++” code:

// sample.cpp
#include <stdio.h>

extern "C" void SayHello()
{
    printf("Hello, World!\n");
}

The above code contains a “SayHello” function which will display a “Hello, World!” message on the screen. Observe that we have used the extern “C” keyword to instruct the compiler to not to generate decorated names. We have already discussed this clearly in our previous article.

Now we will export the “SayHello” function; so, other programming languages can call this function from the DLL. Remember that, in our previous article we have used the “__declspec(dllexport)” keyword to export the function. But in this article we will export the function using “.DEF” file.

Before writing a “.DEF” file, let’s discuss briefly the “.DEF” file.

What is a module definition file (.DEF) & how to define module definition files?

“.DEF” files are module-definition files (text files) that contain module-definition statements that describe various attributes of a DLL. We need to mention the exported function names in the module-definition text file. Commonly we use only two module-definition statements. One is LIBRARY statement and the other one is the EXPORTS statement.

LIBRARY statement must be the first statement in the module definition file; it is followed by the name of the DLL.

EXPORTS statement is required to list the name of the exported functions.

So, our “sample.def” file looks like below:

LIBRARY Sample
   EXPORTS
     SayHello

Now it’s time to generate our DLL file. This is an important step. If we don’t generate the DLL properly, when we try to call the function from the DLL, the application will through the below error message:

The application was unable to start correctly (0xc000007b). Click OK to close the application.

Export functions from a DLL using “.DEF” files

Hence, we need to generate our DLL properly. Remember that we are exporting our function “SayHello” and we are not mentioned this in our “sample.cpp” file; but we have provided the information in “sample.def” file. Because of this, we must include “sample.def” file while generating the DLL. This will add the export functions information into the DLL. So, other programs can call the DLL exported functions. Below is the command to generate the DLL: Run the below command at the command prompt.

cl sample.cpp sample.def /LD

Once we run the above command, it will generate the below files:

sample.dll
sample.exp
sample.lib
sample.obj

Let’s check whether the generated DLL contains exported functions information or not. For this, we can use DUMPBIN utility. DUMPBIN utility will provide information about the format, symbols available in the DLL, library, and executable files. Run the below command to get the information about our “sample.dll”.

dumpbin /exports sample.dll

Once we run the above command at the command prompt; it will display the below information:

c:\>dumpbin /exports sample.dll
Microsoft (R) COFF/PE Dumper Version 11.00.61030.0
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file sample.dll

File Type: DLL

  Section contains the following exports for Sample.dll

    00000000 characteristics
    53BEBDD1 time date stamp Thu Jul 10 21:52:41 2014
        0.00 version
           1 ordinal base
           1 number of functions
           1 number of names

    ordinal hint RVA      name

          1    0 00001000 SayHello

  Summary

        3000 .data
        5000 .rdata
        2000 .reloc
        8000 .text

Observe that, the output displays our “SayHello” function name. That means, our “sample.dll” has our exported function.

Sample application to call exported functions from the DLL

Now we will use a simple test application to call our “SayHello” function from “sample.dll”. Let’s create a simple test application using “Visual F#”.

Step 1. Create a “Visual F#” Windows project using the “F# Application” wizard in Visual Studio 2012 IDE. Visual Studio will create a console-based application.

Step 2. The code generated using “Visual F#” is managed code. But our “sample.dll” was generated by using native code (un-managed code). “.Net Framework” provides “System.Runtime.InteropServices” namespace to allow to use of un-managed code within the managed code. So, we need to add the below statement in our “Visual F#” code to import the “System.Runtime.InteropServices” namespace.

open System.Runtime.InteropServices

Step 3. Use the DllImport attribute in the “Visual F#” code to indicate our “SayHello” function is exposed by an un-managed code.

[<DllImport("sample.dll")>]
extern void SayHello();

We need to specify the full path of the DLL in the DllImport attribute. Or we can place the “sample.dll” into the project’s “bin\Debug” or “bin\Release” folder depending on the project’s configuration. While building the project, if it fails to find the DLL, the compiler will through below error message:

Unhandled Exception: System.DllNotFoundException: Unable to load DLL 'sample.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)

   at Program.SayHello()
   at Program.main(String[] argv) in C:\TestFSharpApp\TestFSharpApp\Program.fs:line 8

Step 4. Call our “SayHello” function.

Here is the actual code:

open System.Runtime.InteropServices

[<DllImport("sample.dll")>]
extern void SayHello();

[<EntryPoint>]
let main argv = 
   SayHello()
    0 // return an integer exit code

Step 5. Build the project. And once we run the project, it will display a “Hello, World!” message on the console window.

It has been proved that our “sample.dll” is working fine from other applications.

**

Visual C++: Exporting functions from a DLL using “.DEF” file.

Leave a Reply

Your email address will not be published. Required fields are marked *

Scroll to top