Utilizing Delphi Codes in VC Without Using a DLL.doc

Embed Size (px)

Citation preview

  • 7/28/2019 Utilizing Delphi Codes in VC Without Using a DLL.doc

    1/4

    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 toolDLL to Libto 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 usualscenario will be: First, make a DLL in Delphi that exports some functions. Then, we call these exportedfunctions in VC. But in this way you have to bundle the Delphi DLLs with your VC application whenever itis 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 inyour 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' inour VC application.

    Write the DLL in Delphi

    First, we write a DLL named JpegLib.dll with Borland Delphi (jpeglib_src.zip), which encapsulates thejpeg.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 filespecified 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 usedDllMain or other similar entry-functions, "DLL to Lib" will generate a correspondingJPEGLIB_DLLMain function declaration header file (JpegLib_supp.h) for you to do necessaryinitialization 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 formore information. Here you can simply click the "Close" button.

    http://www.binary-soft.com/dll2lib/d2l.exehttp://www.binary-soft.com/dll2lib/d2l.exehttp://www.codeguru.com/code/legacy/dll/jpeglib_src.ziphttp://www.binary-soft.com/dll2lib/d2l.exehttp://www.binary-soft.com/dll2lib/d2l.exehttp://www.codeguru.com/code/legacy/dll/jpeglib_src.zip
  • 7/28/2019 Utilizing Delphi Codes in VC Without Using a DLL.doc

    2/4

    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 byJpegLib.dll. You should add them to your project settings when using the corresponding staticlibrary JpegLibst.lib. Click the "Close" button to close the dialog. For detailed information, pleaserefer 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 theresources 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; wehave 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 __cdeclcall convention to process the export symbols. Remember we define LoadJPEG in the cdecl callconvention, so there won't be any problems and we can just ignore this warning. If you want toknow 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 followingequivalent C declaration:

    4. #ifdef __cplusplus5. extern "C" {6. #endif

    7.8. #include 9.10. HBITMAP __cdecl LoadJPEG(LPSTR AFileName);11.12.#ifdef __cplusplus13. }14.#endif

    to a file named JpegLib.h. Note the original Pascal version API of LoadJPEG uses the cdecl callconvention, 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 stackstructure. Moreover, here we use

    extern "C"

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

    Use the Static Library in a VC Application

  • 7/28/2019 Utilizing Delphi Codes in VC Without Using a DLL.doc

    3/4

    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 thedeclaration 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:a. 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, soplease delete it right now.

    b. Copy JpegLib.rc and corresponding external resource files to JpegTest's workingdirectory.

    c. Open the JpegTest project in VC.d. In VC IDE, from the View menu, choose Resource Includes and add the line

    e. #include "JpegLib.rc"

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

    f. Modify the resources IDs or names in the JpegTest project if they conflict with those inJpegLib.dll. (You can refer to JpegLibres.txt.)

    5. Modify JpegTest.cpp bya. Add the line:

    b. #include "JpegLib_supp.h"

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

    d. JPEGLIB_DllMain(AfxGetInstanceHandle(),e. DLL_PROCESS_ATTACH, NULL);

    f. Add a finalization statement to CJpegTestApp::ExitInstance() (you may need to createthis function with ClassWizard first):

    g. JPEGLIB_DllMain(AfxGetInstanceHandle(),h. DLL_PROCESS_DETACH,

    i. 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.a. Add the line:

    b. #include "JpegLib.h"

    c. Add the following code to the click event handler for "Show" button:

    d. void CJpegTestDlg::OnShowButton()e. {

    f. // TODO: Add your control notificationg. // handler code hereh. HBITMAP hBitmap;i.j. UpdateData();k. hBitmap = LoadJPEG((LPSTR)(LPCSTR)m_strFile);l. if(hBitmap) ((CStatic *)GetDlgItem(IDC_JPEGIMAGE))m. ->SetBitmap(hBitmap);n. }

    http://www.codeguru.com/code/legacy/dll/jpeglib_demo.ziphttp://www.codeguru.com/code/legacy/dll/jpeglib_demo.zip
  • 7/28/2019 Utilizing Delphi Codes in VC Without Using a DLL.doc

    4/4

    o. Add JpegLibst.lib, kernel32.lib, gdi32.lib, advapi32.lib, user32.lib, and oleaut32.lib to theobject 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 runwithout JpegLib.dll. The screenshot is shown in the header of this article.

    Downloads

    Download demo project - 12.4 KbDownload source - 100 Kb

    http://www.codeguru.com/code/legacy/dll/jpeglib_demo.ziphttp://www.codeguru.com/code/legacy/dll/jpeglib_src.ziphttp://www.codeguru.com/code/legacy/dll/jpeglib_demo.ziphttp://www.codeguru.com/code/legacy/dll/jpeglib_src.zip