How to put Win32-dependent code outside the main project?

I am writing a program that I want to be portable and want to separate the Win32-specific code out of the main project. My thought was to make a static .lib to handle all the Win32-specific code. I tried making a Windows Console project to create the .exe (which would grow with the addition of the program/"business" logic), and then take the template-generated code from a Windows Desktop project and put it into a static .lib project. I could do the Win32 initialization with a function call to the .lib from the main project. This doesn't work because a wWinApi() in the static .lib needs the information passed to wWinApi when it is the entry point (HINSTANCE in particular).

I tried some variations, such as making the console project an actual Windows Desktop project, but moving all the code out but the entry point function (wWinApi), and moving template-generated resources from to the .lib, but the linker doesn't like this (shown below), and in another configuration, it all compiles fine into an .exe, but explodes at run time.

Anyone have any idea how to have all the Win32-dependent code out of the main project (or what would be a better idea)?

1
2
3
4
5
6
7
8
9
10
11
12
13
2>MSVCRTD.lib(init.obj) : error LNK2019: unresolved external symbol __CrtDbgReport referenced in function __CRT_RTC_INIT
2>MSVCRTD.lib(init.obj) : error LNK2019: unresolved external symbol __CrtDbgReportW referenced in function __CRT_RTC_INITW
2>MSVCRTD.lib(error.obj) : error LNK2019: unresolved external symbol _strcpy_s referenced in function "void __cdecl _RTC_StackFailure(void *,char const *)" (?_RTC_StackFailure@@YAXPAXPBD@Z)
2>MSVCRTD.lib(error.obj) : error LNK2019: unresolved external symbol _strcat_s referenced in function "void __cdecl _RTC_StackFailure(void *,char const *)" (?_RTC_StackFailure@@YAXPAXPBD@Z)
2>MSVCRTD.lib(error.obj) : error LNK2019: unresolved external symbol ___stdio_common_vsprintf_s referenced in function __vsprintf_s_l
2>MSVCRTD.lib(pdblkup.obj) : error LNK2019: unresolved external symbol __wmakepath_s referenced in function "int __cdecl GetPdbDllPathFromFilePath(wchar_t const *,wchar_t *,unsigned int)" (?GetPdbDllPathFromFilePath@@YAHPB_WPA_WI@Z)
2>MSVCRTD.lib(pdblkup.obj) : error LNK2019: unresolved external symbol __wsplitpath_s referenced in function "int __cdecl GetPdbDllPathFromFilePath(wchar_t const *,wchar_t *,unsigned int)" (?GetPdbDllPathFromFilePath@@YAHPB_WPA_WI@Z)
2>MSVCRTD.lib(pdblkup.obj) : error LNK2019: unresolved external symbol _wcscpy_s referenced in function "int __cdecl GetPdbDllPathFromFilePath(wchar_t const *,wchar_t *,unsigned int)" (?GetPdbDllPathFromFilePath@@YAHPB_WPA_WI@Z)
2>MSVCRTD.lib(pdblkup.obj) : error LNK2019: unresolved external symbol ___vcrt_GetModuleFileNameW referenced in function "struct HINSTANCE__ * __cdecl GetPdbDll(void)" (?GetPdbDll@@YAPAUHINSTANCE__@@XZ)
2>MSVCRTD.lib(pdblkup.obj) : error LNK2019: unresolved external symbol ___vcrt_GetModuleHandleW referenced in function "struct HINSTANCE__ * __cdecl GetPdbDll(void)" (?GetPdbDll@@YAPAUHINSTANCE__@@XZ)
2>MSVCRTD.lib(pdblkup.obj) : error LNK2019: unresolved external symbol ___vcrt_LoadLibraryExW referenced in function "struct HINSTANCE__ * __cdecl GetPdbDll(void)" (?GetPdbDll@@YAPAUHINSTANCE__@@XZ)
2>MSVCRTD.lib(chandler4_noexcept.obj) : error LNK2019: unresolved external symbol _terminate referenced in function __except_handler4_noexcept
2>MSVCRTD.lib(chandler4gs.obj) : error LNK2019: unresolved external symbol __except_handler4_common referenced in function __except_handler4
If you're not going to have two projects use the same code, putting the platform-specific code in a separate library doesn't make a lot of sense.
Instead of compartmentalizing by libraries compartmentalize by files. For example:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
//File.h
class File{
    class FileImpl;
    std::unique_ptr<FileImpl> pimpl;
public:
    File(const std::wstring &path);
    //etc.
};

//File_windows.cpp
class FileImpl{
public:
    FileImpl(const std::wstring &path){
        //Call CreateFileW() etc.
    }
};

//File_linux.cpp
class FileImpl{
public:
    FileImpl(const std::wstring &path){
        //Convert to UTF-8, call fopen(), etc.
    }
};
Then you choose to link one file or the other based on the platform.
Last edited on
I'm going to do this. Thanks.
Topic archived. No new replies allowed.