Vulkan and g ++ (undefined reference to 'WinMain')

0

I just downloaded the Khronos graphic library (Vulkan), and I wanted to compile the examples to see how the API works. It turned out that to compile them with the "makefile" (to call it in some way) that comes prepared with the examples is necessary to have the "Visual Studio 2013" :-( thing that does not make me very funny because I have already taken care of MinGW. And in addition the libraries come in format (.lib) instead of (.a) ... The thing is that almost I have compiled an example with g ++ but I have this error.

C:\Users\ivan\Desktop\vulkan>g++ -m64 -std=c++11 -o 01-init_instance.o -LC:/VulkanSDK/1.1.77.0/Bin  vulkan-1.dll
C:/TDM-GCC-64/bin/../lib/gcc/x86_64-w64-mingw32/5.1.0/../../../../x86_64-w64-mingw32/lib/../lib/libmingw32.a(lib64_libmingw32_a-crt0_c.o): In function 'main':
C:/crossdev/src/mingw-w64-v4-git/mingw-w64-crt/crt/crt0_c.c:18: undefined reference to 'WinMain'
collect2.exe: error: ld returned 1 exit status

I'm not sure if it's because of the way I'm compiling and linking (which is the following):

::complile
g++ -m64 -std=c++11 -c -g -Wall  -IC:/VulkanSDK/1.1.77.0/Include   -MMD -MP -MF "01-init_instance.o.d" -o 01-init_instance.o 01-init_instance.cpp

::link
g++ -m64 -std=c++11 -o 01-init_instance.o -LC:/VulkanSDK/1.1.77.0/Bin  vulkan-1.dll 

Or is that the code is missing something, which is the following:

#include <iostream>
#include <cstdlib>
#include <util_init.hpp>

#define APP_SHORT_NAME "vulkansamples_instance"

int sample_main(int argc, char *argv[]) {
    struct sample_info info = {};
    init_global_layer_properties(info);

    /* VULKAN_KEY_START */

    // initialize the VkApplicationInfo structure
    VkApplicationInfo app_info = {};
    app_info.sType = VK_STRUCTURE_TYPE_APPLICATION_INFO;
    app_info.pNext = NULL;
    app_info.pApplicationName = APP_SHORT_NAME;
    app_info.applicationVersion = 1;
    app_info.pEngineName = APP_SHORT_NAME;
    app_info.engineVersion = 1;
    app_info.apiVersion = VK_API_VERSION_1_0;

    // initialize the VkInstanceCreateInfo structure
    VkInstanceCreateInfo inst_info = {};
    inst_info.sType = VK_STRUCTURE_TYPE_INSTANCE_CREATE_INFO;
    inst_info.pNext = NULL;
    inst_info.flags = 0;
    inst_info.pApplicationInfo = &app_info;
    inst_info.enabledExtensionCount = 0;
    inst_info.ppEnabledExtensionNames = NULL;
    inst_info.enabledLayerCount = 0;
    inst_info.ppEnabledLayerNames = NULL;

    VkInstance inst;
    VkResult res;

    res = vkCreateInstance(&inst_info, NULL, &inst);
    if (res == VK_ERROR_INCOMPATIBLE_DRIVER) {
        std::cout << "cannot find a compatible Vulkan ICD\n";
        exit(-1);
    } else if (res) {
        std::cout << "unknown error\n";
        exit(-1);
    }

    vkDestroyInstance(inst, NULL);

    /* VULKAN_KEY_END */

    return 0;
}

All the examples come like this, apparently they have modified the main entry point and they have renamed it like this:

int sample_main(int argc, char *argv[]) 
{
    return 0;
}

And when compiling the error that comes out is because it does not find the entry point defined by Micrisoft:

int CALLBACK WinMain(
  _In_ HINSTANCE hInstance,
  _In_ HINSTANCE hPrevInstance,
  _In_ LPSTR     lpCmdLine,
  _In_ int       nCmdShow
)

{
    return 0;
}

What a mania to change things and create incopatibilities ... with how good one was with the simple main () of all life: -)

Does anyone know what the problem is and how to administer it?

    
asked by Iván Rodríguez 25.07.2018 в 05:12
source

1 answer

0

I do not know what they did but I was able to find a solution. The first thing is to compile this way because in the other way it keeps giving the same problem even if the WinMain function is implemented.

So for C:

gcc -g info.cpp -o info.exe -IC:/VulkanSDK/1.1.77.0/Include  -D_WIN32 -DVK_USE_PLATFORM_WIN32_KHR -LC:/VulkanSDK/1.1.77.0/Lib vulkan-1.dll -mwindows

And so for C ++:

g++ -g info.cpp -o info.exe -IC:/VulkanSDK/1.1.77.0/Include  -D_WIN32 -DVK_USE_PLATFORM_WIN32_KHR -LC:/VulkanSDK/1.1.77.0/Lib vulkan-1.dll -mwindows

And the second thing is to implement the WinMain function in this way.

int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR pCmdLine, int nCmdShow) 
{
    int argc;
    char **argv;

    LPWSTR *commandLineArgs = CommandLineToArgvW(GetCommandLineW(), &argc);
    if (NULL == commandLineArgs) 
    {
        argc = 0;
    }

    if (argc > 0) 
    {
        argv = (char **)malloc(sizeof(char *) * argc);
        if (argv == NULL) {
            argc = 0;
        } else {
            for (int iii = 0; iii < argc; iii++) {
                size_t wideCharLen = wcslen(commandLineArgs[iii]);
                size_t numConverted = 0;

                argv[iii] = (char *)malloc(sizeof(char) * (wideCharLen + 1));
                if (argv[iii] != NULL) {
                    //wcstombs_s(&numConverted, argv[iii], wideCharLen + 1, commandLineArgs[iii], wideCharLen + 1);
                    numConverted = wcstombs(argv[iii], commandLineArgs[iii], wideCharLen + 1);
                }
            }
        }
    } else 
    {
        argv = NULL;
    }


    sample_main(argc, argv);



    // Free up the items we had to allocate for the command line arguments.
    if (argc > 0 && argv != NULL) 
    {
        for (int iii = 0; iii < argc; iii++) 
        {
            if (argv[iii] != NULL) 
            {
                free(argv[iii]);
            }
        }
        free(argv);
    }

}

Well that, problem solved :-). I hope that someone else will also be useful.

    
answered by 25.07.2018 в 09:24