Roberto
Roberto

Reputation: 11

WinMain exported from a DLL

I am trying to hide the WinMain function inside a DLL in order to avoid typing again much of the code over and over again.

I exported wWinMain from the DLL by declaring it as

extern "C" int WINAPI wWinMain( ... ) { // repetitive code here }

and used the linker option /EXPORT:wWinMain, but when I try to use the import library in another project I get the error

LIBCMTD.lib(wincrt0.obj) : error LNK2019: unresolved external symbol _WinMain@16 referenced in function __tmainCRTStartup

Remark I do want to use the GUI interface and I know this is common error when you define a main instead of a WinMain function. Also, I enabled the UNICODE support in both projects. What should I do?

Upvotes: 1

Views: 2442

Answers (6)

user5896498
user5896498

Reputation: 11

//  ...somewhere in a .cpp file within my .dll's sources...
#define WinMain WinMainOld // ...to suppress Win32 declaration of WinMain
#include <windows.h>
#undef WinMain // ...so that WinMain below is not replaced
.   .   . 
#pragma comment(linker, "/export:_WinMain@16") // ...to export it from .dll
extern "C" // ...to suppress C++ name decoration
int CALLBACK WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance,
                     PSTR pCmdLine, int nCmdShow)
{
    .   .   .
}

Upvotes: 1

Thane
Thane

Reputation: 1

EXPORT int WINAPI _WinMain_(int (*_main_)(int argc, char **argv), HINSTANCE hInst, HINSTANCE    hPrevInstance, LPSTR commandLine, int nCmdShow);
int _XMain( int argc, char **argv );

#define XMain   WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrevInstance, LPSTR commandLine, int nCmdShow)\
{return _WinMain_( _XMain, hInst, hPrevInstance, commandLine, nCmdShow );}  \
int _XMain

Then _WinMain_() calls or schedules _XMain().

Over in your application source:

int XMain( int argc, char **argv )
{
}

Upvotes: 0

HungMingWu
HungMingWu

Reputation: 21

I find one way to put WinMain inside DLL.

  • You need to use WinMain instead of wWinMain (I don't know why)
  • Append a def file into your project and,
    append EXPORTS WinMain in def file. Like this

    EXPORTS

    WinMain

    From the observation, all need exported functions generated, not only WinMain.

    After test, the way of __declspec(dllexport) is invalid for WinMain.

  • Link your program to the DLL library use #pragma comment(lib, "testDll.lib") or modify setting in the project.

Upvotes: 0

Necrolis
Necrolis

Reputation: 26181

If you want to call the WinMain of the dll, you need to replace the CRTWinMainStartup function(_tmainCRTStartup in your liked CRT lib), and make it call your exported WinMain, this stops the linker looking for a local WinMain and still keeps correct flow of the program(the source for the CRT startups should be in the crt source of any compiler)

Upvotes: 0

Hans Passant
Hans Passant

Reputation: 942338

This is not possible as-is, the linker can only set the entrypoint for an EXE to a function that's inside the EXE. Rename the wWinMain() in the DLL to something else. Write a wWinMain() in a source code file that gets linked into your EXE, simply call the DLL's exported function.

Upvotes: 2

Boofhead
Boofhead

Reputation: 507

Should you be using WinMain in a DLL? Should it not be DllMain?

Upvotes: 0

Related Questions