Skip to content

Generate import library for exported function of the main executable file #104

@asmwarrior

Description

@asmwarrior

There is a statement in your project home page:

Windows DLL cannot refer to symbols defined in the main application or in previously loaded DLLs.

Some usual solutions exist, but they are not very flexible. A notable exception is the edll library (its homepage also describes the usual solutions), which follows a rather drastic approach; indeed, edll implements a new dynamic linker which can directly load object files (without creating a Windows DLL).

While, it looks like I can do this with the tool gendef and dlltool.

The method I was using is like:

For example, the exe_export.exe has some code like:

#include <Windows.h>
#include <stdio.h>

#define MYDLL_EXPORTS

#include "interface_exe.h"

void appli_printf7777(void)
{
   printf("7777");
   return;
}

void appli_printf8888(void)
{
   printf("8888");
   return;
}


int main(void)
{
   HMODULE hModule = LoadLibrary("dll.dll");
   FARPROC pFunc = GetProcAddress(hModule, "dllFunction");

   ((DLL_FUNC)pFunc)();

   return 0;
}

The content of the interface_exe.h is like below:

#ifndef INTERFACE_EXE_H_INCLUDED
#define INTERFACE_EXE_H_INCLUDED


 #ifdef  MYDLL_EXPORTS
    /*Enabled as "export" while compiling the dll project*/
    #define DLLEXPORT __declspec(dllexport)
 #else
    /*Enabled as "import" in the Client side for using already created dll file*/
    #define DLLEXPORT __declspec(dllimport)
 #endif

#ifdef __cplusplus
extern "C"
{
#endif

typedef void(*DLL_FUNC)(void);

DLLEXPORT void appli_printf7777(void);

DLLEXPORT void appli_printf8888(void);


#ifdef __cplusplus
}
#endif

#endif // INTERFACE_EXE_H_INCLUDED

And I have another dll.cpp file which is used to generate the dll.

#include <Windows.h>
#include <stdio.h>

#include "interface_exe.h"


#ifdef __cplusplus
extern "C"
{
#endif

__declspec (dllexport) void dllFunction(void);

#ifdef __cplusplus
}
#endif




typedef void(*APPLI_PRINTF7)(void);

__declspec(dllexport) void dllFunction(void)
{
   //HMODULE hModule = LoadLibrary("exe_export.exe");
   FARPROC pFunc = GetProcAddress(0, "appli_printf7777");

   if(pFunc)
      ((APPLI_PRINTF7)pFunc)();
   else
      printf("error = %d\n", GetLastError());

   appli_printf7777();
   appli_printf8888();

   return;
}

I first build the exe_export.exe file, and later I use the commands below to generate the import .a file:

gendef exe_export.exe
dlltool --dllname exe_export.exe --def exe_export.def --output-lib libexe_export.a

Then later, I link the libexe_export.a file to generate the dll.

Now, when I run the exe file, I have two methods to call the methods in the dll.

One is using the GetProcAddress method.

   //HMODULE hModule = LoadLibrary("exe_export.exe");
   FARPROC pFunc = GetProcAddress(0, "appli_printf7777");

   if(pFunc)
      ((APPLI_PRINTF7)pFunc)();
   else
      printf("error = %d\n", GetLastError());

The other is using the imported method, which I can directly call

   appli_printf7777();
   appli_printf8888();

All works fine.

Here are some reference:
1, the method I use is described as the .def and .a method, see this discussion:
Enhanced DLL / Discussion / Help and FAQ: The .def and .a method mentioned in the home page

2, https://www.codeproject.com/Articles/17697/Plugin-System-an-alternative-to-GetProcAddress-and
The method mentioned in this link is using MSVC, and I think it is similar with the gendef and dlltool method.

3, my demo code was changed from the sample code in this discussion:
Exporting symbols in a .exe for external DLLs

Hope the above method can help others.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions