Utilizing Delphi Codes in VC Without Using a DLL

Environment: VC 4.1 or higher, Windows 9x/NT/2000/ME/XP

Abstract

This article shows a way to utilize Delphi codes in VC applications without using a DLL. That is, first write a DLL with Delphi, then use a tool—DLL to Lib—to convert it into an equivalent static library, and finally call the static library from VC applications.

Introduction

There are many free codes and components in the Delphi world. How can we utilize them in VC? A usual scenario will be: First, make a DLL in Delphi that exports some functions. Then, we call these exported functions in VC. But in this way you have to bundle the Delphi DLLs with your VC application whenever it is to be released. And the performance of your application will degrade if it uses a lot of tiny DLLs.

To avoid these inconveniences, you can use a tool, “DLL to Lib” (downloadable at http://www.binary-soft.com/dll2lib/d2l.exe), to convert the DLLs into equivalent static libraries, and use the static libraries in your VC application instead of the original DLLs.

Let’s Start with a Demo

We know that Visual C++ doesn’t support the JPEG format directly, whereas Delphi has a unit ‘jpeg.pas’ by which developers can read JPEG images easily. Therefore, we want to utilize the codes of ‘jpeg.pas’ in our VC application.

Write the DLL in Delphi

First, we write a DLL named JpegLib.dll with Borland Delphi (jpeglib_src.zip), which encapsulates the jpeg.pas unit and introduces a simple function, LoadJpeg, to read JPEG images:


function LoadJPEG(AFileName: PChar): HBITMAP; cdecl;

LoadJPEG returns the handle to a Windows bitmap holding the image data extracted from the JPEG file specified by AFileName.

Convert DLL into a Static Library

Second, let’s convert JpegLib.dll into a static library. Start “DLL to Lib”, then:

  1. Select JpegLib.dll in the “The DLL file to be converted” edit box.
  2. Since JpegLib.dll has no accompanying import libraries, we have to leave the “Import Lib Files for the DLL” list empty.
  3. Input JpegLibst.lib in the “Output Static Library File” edit box. We want “DLL to Lib” to produce a static library named JpegLibst.lib.
  4. Leave all other options intact and click “Start Convert” to convert the JpegLib.dll into JpegLibst.lib.
  5. After a while, you will see a dialog box saying “Converting JpegLib.dll into JpegLibst.lib successfully”; click “OK”.
  6. You will see a dialog box titled “Header file for DllMain”. Because your JpegLib.dll has used DllMain or other similar entry-functions, “DLL to Lib” will generate a corresponding JPEGLIB_DLLMain function declaration header file (JpegLib_supp.h) for you to do necessary initialization and finalization before using any other functions in the generated static library. Please see the “convert entry-point function in DLL” topic in “DLL to Lib”‘s help document for more information. Here you can simply click the “Close” button.
  7. You will see a dialog box titled “Import Libraries Required” telling you that five import libraries, namely KERNEL32.LIB, GDI32.LIB, ADVAPI32.LIB, USER32.LIB, and OLEAUT32.LIB, are used by JpegLib.dll. You should add them to your project settings when using the corresponding static library JpegLibst.lib. Click the “Close” button to close the dialog. For detailed information, please refer to the “Add Import Libraries to Your project” topic in “DLL to Lib”‘s help document.
  8. You will see a dialog box titled “Resource names or IDs used by dll” telling you about the resources used in JpegLib.dll. Save it to JpegLibres.txt for further reference and close the dialog.
  9. Analyzing the log list, we find a warning:

    Warning 10: Cannot find corresponding export symbol for LoadJPEG in the import libraries; we have to assume the export symbol follows __cdecl call convention.

    This warning means “DLL to Lib” cannot find the export symbol of the DLL in the import library (because you have not provided any import libraries), so “DLL to Lib” will use the default __cdecl call convention to process the export symbols. Remember we define LoadJPEG in the cdecl call convention, so there won’t be any problems and we can just ignore this warning. If you want to know more information about call the convention, please refer to the “__cdecl call convention” topic in “DLL to Lib”‘s help document.

We now have successfully converted JpegLib.dll into a static library JpegLibst.lib.

Rewrite DLL APIs in C

Now we will use JpegLibst.lib in our VC applications. Since JpegLib.dll does not provide a c header file, we have to write one for ourselves:

  1. From JpegLib.dll’s source code, we know the pascal API for LoadJPEG is:

  2. function LoadJPEG(AFileName: PChar): HBITMAP; cdecl;

  3. According to the rules of type conversion between Delphi and C, we can write out the following equivalent C declaration:


    #ifdef __cplusplus
    extern “C” {
    #endif

    #include <windows>

    HBITMAP __cdecl LoadJPEG(LPSTR AFileName);

    #ifdef __cplusplus
    }
    #endif

    to a file named JpegLib.h. Note the original Pascal version API of LoadJPEG uses the cdecl call convention, so you must also use __cdecl in the C declaration. If you use other call conventions, an unexpected exception will be raised because of the incompatible parameter order and stack structure. Moreover, here we use


    extern “C”

    in the declaration to prevent the compiler from mangling the function name (which will lead to unresolved symbol errors when linked with the static library).

Use the Static Library in a VC Application

Now we can open the demo project JpegTest (jpeglib_demo.zip) to test the static library:

  1. Copy the static library JpegLibst.lib to JpegTest’s working directory.
  2. Copy the header file JpegLib_supp.h to JpegTest’s working directory. Remember it contains the declaration for JPEGLIB_DllMain.
  3. Copy the DLL’s declaration header file JpegLib.h to JpegTest’s working directory.
  4. Since the code in JpegLibst.lib may use the resources in JpegLib.dll, we must add these resources into JpegTest project. To do this, we:
    1. Open JpegLib.dll in Visual C++ as resources and save them to a JpegLib.rc file. Visual C++ will generate a new resource.h when saving JpegLib.rc, but it is of no use, so please delete it right now.
    2. Copy JpegLib.rc and corresponding external resource files to JpegTest’s working directory.
    3. Open the JpegTest project in VC.
    4. In VC IDE, from the View menu, choose Resource Includes and add the line


      #include “JpegLib.rc”

      to the “Compile-time directives” box. Note: a message box will pop up after you modify the resource includes; just click “OK” to close it.

    5. Modify the resources IDs or names in the JpegTest project if they conflict with those in JpegLib.dll. (You can refer to JpegLibres.txt.)
  5. Modify JpegTest.cpp by
    1. Add the line:

    2. #include “JpegLib_supp.h”

    3. Add an initialization statement to CJpegTestApp::InitInstance():

    4. JPEGLIB_DllMain(AfxGetInstanceHandle(),
      DLL_PROCESS_ATTACH, NULL);

    5. Add a finalization statement to CJpegTestApp::ExitInstance() (you may need to create this function with ClassWizard first):


      JPEGLIB_DllMain(AfxGetInstanceHandle(),
      DLL_PROCESS_DETACH,
      NULL);

      the detail information about call entry-point function in DLL can be found in the topic ‘Convert Entry-Point Function in DLL’ in help document of “DLL to Lib”.

  6. Open JpegTestDlg.cpp.
    1. Add the line:

    2. #include “JpegLib.h”

    3. Add the following code to the click event handler for “Show” button:

    4. void CJpegTestDlg::OnShowButton()
      {
      // TODO: Add your control notification
      // handler code here

      HBITMAP hBitmap;

      UpdateData();
      hBitmap = LoadJPEG((LPSTR)(LPCSTR)m_strFile);
      if(hBitmap) ((CStatic *)GetDlgItem(IDC_JPEGIMAGE))
      ->SetBitmap(hBitmap);
      }

    5. Add JpegLibst.lib, kernel32.lib, gdi32.lib, advapi32.lib, user32.lib, and oleaut32.lib to the object module list of the project.
  7. Now we can build the JpegTest project by click F7. Wait…. Okay. The project is built successfully.
  8. Run JpegTest, select a JPEG filename, and click “Show it”. Okay; the JPEG image is shown in our dialog. We have ported the Delphi code to VC application JpegTest successfully. And it can run without JpegLib.dll. The screenshot is shown in the header of this article.

Downloads

Download demo project – 12.4 Kb

Download source – 100 Kb

More by Author

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Must Read