How to correctly build code for gcc with netapi32? - c

I just try build this example for GCC.
But I got several problems.
My system is:
Win10
msys64 with ucrt64 (x86_64-w64-mingw32)
c:\windows\servicing\LCU\Package_for_RollupFix~31bf3856ad364e35~amd64~~19041.2486.1.5\amd64_microsoft-windows-netapi32_31bf3856ad364e35_10.0.19041.2130_none_0202483cb6bb2fc6\f\netapi32.dll
Atom as IDE (I have not VS)
cmd as console
I try: gcc main.c -o main.exe -lnetapi32
But gcc returned:
undefined reference to `WinMain' collect2.exe: error: ld returned 1 exit status
OK - wrong entry point.
Changed wMain in WinMain.
Result:
main.c:11:5: error: conflicting types for 'WinMain'; have 'int(int, wchar_t **)' {aka 'int(int, short unsigned int **)'}
11 | int WinMain(int argc, wchar_t *argv[])
| ^~~~~~~
In file included from c:/msys64/ucrt64/include/windows.h:70,
from main.c:8:
c:/msys64/ucrt64/include/winbase.h:1128:14: note: previous declaration of 'WinMain' with type 'int(struct HINSTANCE__ *, struct HINSTANCE__ *, CHAR *, int)' {aka 'int(struct HINSTANCE__ *, struct HINSTANCE__ *, char *, int)'}
1128 | int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd);
What is wrong?

wmain is an extension by Microsoft, and insofar I know not supported by gcc. You need to change the entry function to a standard int main(int argc, char **args). You can also use WinMain but then you'll have to use int WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)

Related

how to load images in sdl to a surface in c using IMG_Load?

When I run
SDL_Surface* surface = IMG_Load("*image location*");
an error pops up saying
initialization of 'SDL_Surface *' {aka 'struct SDL_Surface *'} from 'int' makes pointer from integer without a cast [-Wint-conversion]
I don't know why this happening because shouldn't IMG_load be returning a pointer
https://www.libsdl.org/projects/SDL_image/docs/SDL_image_11.html
here is the rest of the code
#include <stdio.h>
#include <windows.h>
#include <SDL2\SDL.h>
int WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nShowCmd)
{
int result = SDL_Init(SDL_INIT_EVERYTHING);
SDL_Window *window = SDL_CreateWindow("bruh",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,500,500,0);
SDL_Renderer *rend = SDL_CreateRenderer(window,-1,SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC);
SDL_Surface* surface = IMG_Load("*image location*");
SDL_Texture* texture = SDL_CreateTextureFromSurface(rend,surface);
SDL_FreeSurface(surface);
SDL_RenderClear(rend);
SDL_RenderCopy(rend,texture,NULL,NULL);
SDL_RenderPresent(rend);
SDL_Delay(5000);
SDL_DestroyTexture(texture);
SDL_DestroyRenderer(rend);
SDL_DestroyWindow(window);
SDL_Quit();
return 0;
}
how do I fix this error?
IMG_Load belongs to separate libary SDL_image. This function is declared in SDL_image.h, which you didn't include. Add that include and link with appropriate library. In C undeclared functions are allowed via implicit declarations, and implicitly declared function returns int, that's where your error comes from.
Sane compiler will issue a warning about implicit declaration. Warnings are there for a reason, read them and don't suppress warnings unless you're absolutely certain.

mingw g++ Windows Subsystem WinMain not getting hInstance value

I'm converting a VS2015 C++ directx/winforms app to VS code using mingw G++ (both on windows 10).
I have it compiling and linking after adding the -mwindows option (and a whole bunch of libraries) but upon stepping into the WinMain there is no value in hInstance.
#include <objbase.h>
#include <windows.h>
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{
LoadString(hInstance, IDS_APP_TITLE,g_szAppName, MAX_LOADSTRING);
...
Which results in anything depending on it like LoadString or RegisterClassEx not working.
What should I be looking for?

argument of type const char* is incompatible with parameter of type "LPCWSTR"

I am trying to make a simple Message Box in C in Visual Studio 2012, but I am getting
the following error messages
argument of type const char* is incompatible with parameter of type "LPCWSTR"
err LNK2019:unresolved external symbol_main referenced in function_tmainCRTStartup
Here is the source code
#include<Windows.h>
int _stdcall WinMain(HINSTANCE hinstance,HINSTANCE hPrevinstance,LPSTR lpszCmdline,int nCmdShow)
{
MessageBox(0,"Hello","Title",0);
return(0);
}
Please Help
Thanks and Regards
To compile your code in Visual C++ you need to use Multi-Byte char WinAPI functions instead of Wide char ones.
Set Project -> Properties -> General -> Character Set option to Use Multi-Byte Character Set
I found it here https://stackoverflow.com/a/33001454/5646315
To make your code compile in both modes, enclose the strings in _T() and use the TCHAR equivalents
#include <tchar.h>
#include <windows.h>
int WINAPI _tWinMain(HINSTANCE hinstance, HINSTANCE hPrevinstance, LPTSTR lpszCmdLine, int nCmdShow)
{
MessageBox(0,_T("Hello"),_T("Title"),0);
return 0;
}
I recently ran in to this issue and did some research and thought I would document some of what I found here.
To start, when calling MessageBox(...), you are really just calling a macro (for backwards compatibility reasons) that is calling either MessageBoxA(...) for ANSI encoding or MessageBoxW(...) for Unicode encoding.
So if you are going to pass in an ANSI string with the default compiler setup in Visual Studio, you can call MessageBoxA(...) instead:
#include<Windows.h>
int _stdcall WinMain(HINSTANCE hinstance,HINSTANCE hPrevinstance,LPSTR lpszCmdline,int nCmdShow)
{
MessageBoxA(0,"Hello","Title",0);
return(0);
}
Full documentation for MessageBox(...) is located here: https://msdn.microsoft.com/en-us/library/windows/desktop/ms645505(v=vs.85).aspx
And to expand on what #cup said in their answer, you could use the _T() macro and continue to use MessageBox():
#include<tchar.h>
#include<Windows.h>
int _stdcall WinMain(HINSTANCE hinstance,HINSTANCE hPrevinstance,LPSTR lpszCmdline,int nCmdShow)
{
MessageBox(0,_T("Hello"),_T("Title"),0);
return(0);
}
The _T() macro is making the string "character set neutral". You could use this to setup all strings as Unicode by defining the symbol _UNICODE before you build (documentation).
Hope this information will help you and anyone else encountering this issue.
Yes whatever it was it was a wrong tutorial, you need to make it a long byte integer.
Try this:
#include<Windows.h>
int _stdcall WinMain(HINSTANCE hinstance,HINSTANCE hPrevinstance,LPSTR lpszCmdline,int nCmdShow)
{
MessageBox(0,L"Hello",L"Title",0);
return(0);
}

GCC Win32 API Linking Issue with ComCtl32

I can't get Comctl32.lib to link with my program using GCC (MinGW).
GCC Input:
gcc -o program.exe main.c images.o -lgdi32 -lcomctl32 -mwindows
GCC Output
main.c: In function 'WinMain':
main.c:120:2: error: unknown type name 'INITCOMMONCONTROLSEX'
main.c:124:9: error: request for member 'dwICC' in something not a structure or union
Related Code in main.c
#define _WIN32_WINNT _WIN32_WINNT_WIN7
#include <windows.h>
#include <commctrl.h>
int WINAPI WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmd)
{
Line 120: INITCOMMONCONTROLSEX icex;
Line 124: icex.dwICC = ICC_LISTVIEW_CLASSES;
InitCommonControlsEx(&icex);
}
Thank you for any help or information you can provide. I've been at this too long and just can't come up with an answer.
I have resolved the issue thanks to David H. I had to define
#define _WIN32_IE 0x0900
I was under the impression that commctrl.h was defining 0x0500 by default (0x0300 is required for my functions), but it appears it wasn't.
If you do not define the _WIN32_IE macro in your project, it is automatically defined as 0x0500. - MSDN Source

Weird Error in WinMain() to main() Macro

/** converts 'WinMain' to the traditional 'main' entrypoint **/
#define PRO_MAIN(argc, argv)\
int __main (int, LPWSTR*, HINSTANCE, int);\
int WINAPI WinMain (HINSTANCE __hInstance, HINSTANCE __hPrevInstance, \
LPSTR __szCmdLine, int __nCmdShow)\
{\
int nArgs;\
LPWSTR* szArgvW = CommandLineToArgvW (GetCommandLineW(), &nArgs);\
assert (szArgvW != NULL);\
return __main (nArgs, szArgvW, __hInstance, __nCmdShow);\
}\
\
int __main (int __argc, LPWSTR* __argv, HINSTANCE __hInstance, int __nCmdShow)
Now, when I use this code here:
PRO_MAIN(argc, argv)
{
...
}
I get the error:
error: conflicting types for '__main'
note: previous declaration of '__main' was here
What's the problem?
You have broken the rules: double-underscores are reserved for implementation! (Among other things.)
You simply cannot use __main, main__, _Main, etc. You should pick something else.
I would recommend you make this work:
int main(int argc, char* argv[])
{
// main like normal
}
// defines WinMain, eventually makes call to main()
PRO_MAIN;
Which has the added advantage that for non-Windows applications, PRO_MAIN can simply expand to nothing, and the program still compiles with the standard main function. This is what I do.

Resources