Undefined reference to `StringCbPrintfW' when compiling Win32 app - c

I'm trying to compile a Win32 app with MinGW, whose code can be found here. The source code compiles into an object just fine, but when I try and link it, this happens:
> gcc -o bin\updown.exe obj\updown.o -s -lcomctl32 -Wl,--subsystem,windows
obj\updown.o:updown.c:(.text+0x3ac): undefined reference to `StringCbPrintfW'
collect2.exe: error: ld returned 1 exit status
The only time this function appears is in the following snippet:
#include <windows.h>
#include <commctrl.h>
#include <strsafe.h>
...
LRESULT CALLBACK WndProc(HWND hwnd, UINT msg,
WPARAM wParam, LPARAM lParam) {
LPNMUPDOWN lpnmud;
UINT code;
switch(msg) {
...
case WM_NOTIFY:
...
const int asize = 4;
wchar_t buf[asize];
size_t cbDest = asize * sizeof(wchar_t);
StringCbPrintf(buf, cbDest, L"%d", value);
SetWindowText(hStatic, buf);
}
break;
...
}
...
}

Your project can define STRSAFE_LIB before including strsafe.h, and then link to strsafe.lib. Note that strsafe.h will use a #pragma comment(lib, "strsafe.lib") statement if STRSAFE_LIB is defined, but I don't know if that pragma works in MinGW or not, so you may have to link to the .lib manually.

Related

BOOL not recognized as data type (C...?) [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 6 years ago.
Improve this question
I'm trying to compile an application from source code with Visual Studio 2015 Enterprise. I've run into some problems.
When I try to compile, I get several errors related to BOOL being an undefined type. I've tried including winmindef.h and windef.h to no avail. Here's some of the function declarations in the code that throw errors:
void GetCheatName ( int CheatNo, char * CheatName, int CheatNameLen );
BOOL LoadCheatExt ( char * CheatName, char * CheatExt, int MaxCheatExtLen);
void RefreshCheatManager ( void );
void SaveCheatExt ( char * CheatName, char * CheatExt );
BOOL TreeView_GetCheckState(HWND hwndTreeView, HTREEITEM hItem);
BOOL TreeView_SetCheckState(HWND hwndTreeView, HTREEITEM hItem, BOOL fCheck);`
When I include the following in the .h file, the problem is still not resolved
#ifndef TRUE
#define TRUE 1
#endif
#ifndef FALSE
#define FALSE 0
#endif
typedef int BOOL;
If it helps, I am trying to compile PJ64, and may need to change some setting in order to compile, but I'm not sure which.
Any help at all is appreciated!
---UPDATE---
Here are the complete compile errors (I've omitted most of the warnings):
1>cl : Command line warning D9007: '/Gm' requires '/Zi or /ZI'; option ignored
1> Cheat.c
1>Cheat.c(55): error C2059: syntax error: '<parameter-list>'
1>Cheat.c(56): error C2059: syntax error: '{'
1>Cheat.c(233): warning C4267: '=': conversion from 'size_t' to 'WORD', possible loss of data
1>Cheat.c(326): warning C4267: '=': conversion from 'size_t' to 'WORD', possible loss of data
1>Cheat.c(346): warning C4267: '=': conversion from 'size_t' to 'WORD', possible loss of data
1>Cheat.c(982): error C2059: syntax error: '<parameter-list>'
1>Cheat.c(998): error C2059: syntax error: '{'
1>Cheat.c(999): error C2449: found '{' at file scope (missing function header?)
1>Cheat.c(1012): error C2059: syntax error: '}'
The complete code for the project I am trying to compile can be found here.
This is -part- of the code that was compiled and threw the above errors. I've left the vast majority of the code out because it is too lengthy to include here. I've left comments indicating which lines threw errors.
#include <Windows.h>
#include <windowsx.h>
#include <commctrl.h>
#include <windef.h>
#include <stdio.h>
#include "main.h"
#include "cheats.h"
#include "cpu.h"
#include "resource.h"
#define UM_CHECKSTATECHANGE (WM_USER + 100)
#define UM_CHANGECODEEXTENSION (WM_USER + 101)
#define IDC_MYTREE 0x500
#define MaxCheats 300
#define SelectCheat 1
#define EditCheat 2
#define NewCheat 3
HWND hManageWindow = NULL;
HWND hSelectCheat, hAddCheat, hCheatTree;
CHEAT_CODES Codes[MaxCheats];
int NoOfCodes;
void GetCheatName ( int CheatNo, char * CheatName, int CheatNameLen );
BOOL LoadCheatExt ( char * CheatName, char * CheatExt, int MaxCheatExtLen);
void RefreshCheatManager ( void );
void SaveCheatExt ( char * CheatName, char * CheatExt );
BOOL TreeView_GetCheckState(HWND hwndTreeView, HTREEITEM hItem); //(line 55, error thrown.)
BOOL TreeView_SetCheckState(HWND hwndTreeView, HTREEITEM hItem, BOOL fCheck); //(line 56)
LRESULT CALLBACK ManageCheatsProc (HWND, UINT, WPARAM, LPARAM );
void ApplyCheats (void) {
//lots 'o code
}
BOOL CheatActive (char * Name) {
//more code
}
LRESULT CALLBACK CheatsCodeExProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
//Too much code to contain in this post...
}
LRESULT CALLBACK CheatsCodeQuantProc (HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam) {
//code
}
//Because of the inmensity of code, I will skip to the lines that throw errors.
BOOL TreeView_GetCheckState(HWND hwndTreeView, HTREEITEM hItem) { //line 982, error thrown.
//code here
}
BOOL TreeView_SetCheckState(HWND hwndTreeView, HTREEITEM hItem, BOOL fCheck) //line 999, error thrown
{ //line 1000, error thrown
//Lots o code
} // line 1013, error thrown
If more code is desired, I'll gladly post!
I've checked the code you gave a link to.
BOOL type is properly included. To check that you can compile Cheat.c with /P option.
All the problems are caused by upgrade of the project from Visual Studio 6 to Visual Studio 2015.
If you will investigate the pre-processor ouput you will see the transformation:
BOOL TreeView_GetCheckState(HWND hwndTreeView, HTREEITEM hItem); //(line 55, error thrown.)
BOOL TreeView_SetCheckState(HWND hwndTreeView, HTREEITEM hItem, BOOL fCheck); //(line 56)
pre-processed to:
BOOL ((((UINT)(SendMessageA((HWND hwndTreeView), (0x1100 + 39), (WPARAM)(HTREEITEM hItem), 0xF000))) >> 12) -1);
BOOL { TVITEMA _ms_TVi; _ms_TVi.mask = 0x0008; _ms_TVi.hItem = (HTREEITEM hItem); _ms_TVi.stateMask = (0xF000); _ms_TVi.state = ((((BOOL fCheck)?2:1) << 12)); SendMessageA((HWND hwndTreeView), (0x1100 + 13), 0, (LPARAM)(TVITEMA *)&_ms_TVi);};
It's not what you expect to see in your function declarations.
Both of these TreeView_GetCheckState and TreeView_SetCheckState are standard macroses defined in CommCtrl.h. Remove your old functions and use these macroses.

sendmessage callback error in visual studio 2012

sendmessage callback error in visual studio 2012
I am recieving following errors in this C function?
error C2220: warning treated as error - no 'object' file generated
warning C4100: 'wParam' : unreferenced formal parameter
warning C4100: 'hwnd' : unreferenced formal parameter
LRESULT CALLBACK WndProc (HWND hwnd,UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message) {
case WM_COPYDATA:
{
COPYDATASTRUCT* copy_data = (COPYDATASTRUCT*)(lParam);
const char* str = (const char* )(copy_data->lpData);
/* Also fixed the parameter list for "%.*s" */
printf("Message (%u): %.*s\n", copy_data->dwData, (int)copy_data->cbData, str);
}
}
}
The error is that you told the compiler to treat warnings as errors, and you have two warnings about arguments that is not used in the function.
The simplest solution is to actually skip naming those arguments, like so:
LRESULT CALLBACK WndProc (HWND, UINT message, WPARAM, LPARAM lParam)
For a solution working in C, then you have to actually use the arguments, even if you don't do anything with them. This can be done with e.g. using them in an expression and throw away the result, like
(void) hwnd;
(void) wParam;
Or use the macros defined in winnt.h (which should be included for you by default) for this:
UNREFERENCED_PARAMETER(hwnd);
UNREFERENCED_PARAMETER(wParam);
See e.g. this article.

Undefined reference adding to existing file and header

first of all I know this is asked a thousand times. But I opened a few and everyone forgot to compile/link it with it.
Anyway I created a linked list in a separate file with header and file, which works fine, however I tried to add a new function to it but then I have undefined reference to 'function.' Here is the source:
list.c
#include "list.h"
struct node
{
item_t x;
struct node *next;
};
struct node* root;
//Window hider extension
void ToggleVisibleList(HWND currentHwnd)
{
if (root == 0)
return;
struct node *conductor = root;
while (conductor != 0)
{
HWND hwnd = (HWND)conductor->x;
ShowWindow(hwnd, IsWindowVisible(hwnd) ? SW_HIDE : SW_SHOW);
conductor = conductor->next;
}
ShowWindow(currentHwnd, IsWindowVisible(currentHwnd) ? SW_HIDE : SW_SHOW);
}
//...Rest of the file
list.h
#ifndef LIST_H
#define LIST_H
#include <stdlib.h>
#include <windows.h>
//Window hider extension
void ToggleVisibleList(HWND currentHwnd);
//.. rest of the header
main.c
#include <windows.h>
#include <stdio.h>
#include <commctrl.h>
#include "list.h"
HWND currentHwnd;
//..
HHOOK hookKeyboard;
LRESULT CALLBACK LowLevelKeyboardProc(int nCode, WPARAM wParam, LPARAM lParam)
{
if (nCode >= 0)
{
if (wParam == WM_KEYDOWN)
{
KBDLLHOOKSTRUCT* hookStruct = (KBDLLHOOKSTRUCT*)lParam;
if (hookStruct->vkCode == 'Z' && GetAsyncKeyState(VK_LCONTROL))
{
ToggleVisibleList(currentHwnd);
}
}
}
CallNextHookEx(hookKeyboard, nCode, wParam, lParam);
}
//..Rest of file
I compile using Mingw (OS: Windows 8 64-bit):
gcc -o hider.exe main.c list.c -mwindows
C:\Users\...\AppData\Local\Temp\cc6sCa17.o:main.c:(.text+0x4bc): undefined reference to `ToggleVisibleList'
collect2: ld gaf exit-status 1 terug
//Translation: ld return exit-status 1
EDIT: Tried swapping the file order.
I hope I didn't duplicate a question, I don't think so because I've tried 20 questions first. (And google.)
Regards
Answer: rebooted my computer and it compiled.
Total shot in the dark answer:
I suspect this might work (swap list.c and main.c in the compile order)
gcc -o hider.exe list.c main.c -mwindows
I suggest this because linking with libraries has similar behavior with gcc. But I've never observed this problem with file order.
Fromt the gcc man page (in regards to -l library)
It makes a difference where in the command you write this option; the
linker searches and processes
libraries and object files in the order they are specified. Thus, foo.o -lz bar.o searches library
z after file foo.o but before bar.o. If bar.o refers to functions in z, those functions may not be
loaded.

Can't link against WICConvertBitmapSource

I'd like to use a function from WindowsCodecs.dll, but MinGW has incomplete and missing WinAPI headers, as well as import libraries. Consider the following demo:
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#include <stdio.h>
// ---------- dummy declarations, because MinGW got no wincodec.h ----------
typedef REFGUID REFWICPixelFormatGUID;
typedef VOID IWICBitmapSource;
HRESULT WINAPI WICConvertBitmapSource(
REFWICPixelFormatGUID dstFormat,
IWICBitmapSource *pISrc,
IWICBitmapSource **ppIDst);
// -------------------------------------------------------------------------
int WINAPI WinMain(HINSTANCE hInst, HINSTANCE hPrev, LPSTR lpLine, int nShow)
{
#ifdef LOAD_FROM_DLL
typedef HRESULT (WINAPI *PWICConvertBitmapSource)(
REFWICPixelFormatGUID, IWICBitmapSource *, IWICBitmapSource **);
HMODULE hDll = LoadLibrary("WindowsCodecs.dll");
PWICConvertBitmapSource pFunc =
(PWICConvertBitmapSource)GetProcAddress(hDll, "WICConvertBitmapSource");
printf("WICConvertBitmapSource: 0x%p.\n", pFunc);
pFunc(NULL, NULL, NULL);
FreeLibrary(hDll);
#else
WICConvertBitmapSource(NULL, NULL, NULL);
#endif
return 0;
}
When built by gcc test.c -DLOAD_FROM_DEF, the program prints address of the function and terminates correctly. Although, when linked against the import library from the following def:
LIBRARY WindowsCodecs.dll
EXPORTS
WICConvertBitmapSource#12
, this error pops out:
The procedure entry point WICConvertBitmapSource#12 could
not be located in the dynamic link library WindowsCodecs.dll.
Surprisingly enough, if I remove the declaration of WICConvertBitmapSource from the source and #12 from def file, the program links and runs fine.
How can I create a correct import library?
Notes: I'm running MinGW on Windows 7 SP1. My gcc version is 4.7.0 with w32api 3.17 installed. The problem appears with many functions, like GdiAlphaBlend, or SHCreateStreamOnFileEx.
The import library should've been created with --kill-at flag, like this:
dlltool --kill-at -D WindowsCodecs.dll -d WindowsCodecs.def -l libwindowscodecs.a
This article clarified everything for me: http://wyw.dcweb.cn/stdcall.htm

How to specify dll onload function for mingw32?

I can compile DLLs properly using mingw and do the exports/imports stuff. What I am looking for is defining the dll onload function properly as you would in MS VC products. Google didn't turn up anything. Anyone have any ideas or a link to a tutorial?
Okay, so after some fiddling...it's working. For anyone else that is having issues here it is. My issues weren't related to compiling in instead of loading dynamically. It was a mash-up of a couple of tutorial/question/how-tos that got me to this point.
dll.c
#include <stdio.h>
#include <windows.h>
#include "dll.h"
//extern "C" BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD Reason, LPVOID LPV) {
//This one was only necessary if you were using a C++ compiler
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) {
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
// Code to run when the DLL is loaded
printf ("Load working...\n");
break;
case DLL_PROCESS_DETACH:
// Code to run when the DLL is freed
printf ("Unload working...\n");
break;
case DLL_THREAD_ATTACH:
// Code to run when a thread is created during the DLL's lifetime
printf ("ThreadLoad working...\n");
break;
case DLL_THREAD_DETACH:
// Code to run when a thread ends normally.
printf ("ThreadUnload working...\n");
break;
}
return TRUE;
}
EXPORT void hello(void) {
printf ("Hello\n");
}
dll.h
#ifndef DLL_H_
#define DLL_H_
#ifdef BUILD_DLL
/* DLL export */
#define EXPORT __declspec(dllexport)
#else
/* EXE import */
#define EXPORT __declspec(dllimport)
#endif
EXPORT void hello(void);
#endif /* DLL_H_ */
hello.c
#include <windows.h>
#include <stdio.h>
int main () {
/*Typedef the hello function*/
typedef void (*pfunc)();
/*Windows handle*/
HANDLE hdll;
/*A pointer to a function*/
pfunc hello;
/*LoadLibrary*/
hdll = LoadLibrary("message.dll");
/*GetProcAddress*/
hello = (pfunc)GetProcAddress(hdll, "hello");
/*Call the function*/
hello();
return 0;
}
when compiled with
gcc -c -DBUILD_DLL dll.c
gcc -shared -o message.dll dll.o -Wl,--out-implib,libmessage.a
gcc -c hello.c
gcc -o hello.exe hello.o message.dll
produces the expected output of
Load working...
Hello
Unload working...
Since mingw is just a windows port of GCC and associated tools, you can use GCC constructor and destructor attributes. These work for both shared and static libraries, and execute code before and after main is run, respectively. Additionally, you can specify multiple constructor and destructor functions per library.
static void __attribute__((constructor))
your_lib_init(void)
{
fprintf(stderr, "library init\n");
}
static void __attribute__((destructor))
your_lib_destroy(void)
{
fprintf(stderr, "library destroy\n");
}

Resources