How to solve the 'undefined reference to' in C program? - c

#include <stdio.h>
#include <stdlib.h>
#include <winscard.h>
#include <wintypes.h>
int main(void){
SCARDCONTEXT hContext;
SCARDHANDLE hCard;
DWORD dwActiveProtocol;
LONG rv;
rv = SCardEstablishContext(SCARD_SCOPE_SYSTEM,NULL,NULL,&hContext);
rv = SCardConnect(hContext,"Reader X", SCARD_SHARE_SHARED,
SCARD_PROTOCOL_T0, &hCard, &dwActiveProtocol);
printf("Hello world!\n");
}
There are errors like this:
test.c:(.text+0x2e): undefined reference to `SCardEstablishContext'
test.c:(.text+0x5b): undefined reference to `SCardConnect'
xcollect2: error: ld returned 1 exit status
The functions are included in 'winscard.h' but it seems I cannot use them.
I don't know how to solve it.

Including a header file usually just informs your translation unit (your program in this case) that certain things exist, in order than the code can be compiled,
To actually use those things, you need to do more than just figure out that they exist, you need to actually incorporate the code for them within your executable.
This is generally the responsibility of the link stage and, as per the Microsoft documentation, the code for these functions are to be found in winscard.lib/.dll. You need to modify your project so that those libraries are included in your build.

Related

Undefined reference ld error when using Windows <bluetoothapis.h>

I am new to programming and want to work with the Windows BluetoothApi.h library in C. I've written smaller programs that reference header files I've created, but none of the APIs given by windows.
I am attempting to return information from a local bluetooth speaker to a terminal session on my PC. I've been referencing the BluetoothFindFirstRadio and BLUETOOTH_FIND_RADIO_PARAM documentation, as well as some posts on Stack to see some viable examples. I believe I'm close to being able to compile but I keep getting an error about an undefined reference to the functions I'm calling that I do believe are in the BluetoothAPI.h header file.
From what I've seen, again on Stack, it seems that it's possible that "there is not enough space left at \user\tmp"?
or
Looking at the documentation for ld, it may be possible I need to try to compile using a different command altogther?
PS C:\scripts\C_Lang\Bluetooth> gcc bluetest.c -o test
C:\Users\Ryan\AppData\Local\Temp\cce0FxKH.o:bluetest.c:(.text+0x2b): undefined reference to `BluetoothFindFirstRadio#8'
C:\Users\Ryan\AppData\Local\Temp\cce0FxKH.o:bluetest.c:(.text+0x48): undefined reference to `BluetoothFindRadioClose#4'
collect2.exe: error: ld returned 1 exit status
Code is below:
#include <stdio.h>
#include <string.h>
#include <Windows.h> //not sure if needed
#include <Ws2bth.h> //not sure if needed
#include <bthsdpdef.h>
#include bluetoothapis.h>
//#include <bluetoothleapis.h>
#pragma comment(lib, "Bthprops.lib");
int main(void)
{
BLUETOOTH_FIND_RADIO_PARAMS btfrp; // structure
btfrp.dwSize = sizeof(btfrp); // creating space in memory for parameters?
HANDLE hRadio; // not sure what a handle is, something similar to a pointer?
HBLUETOOTH_RADIO_FIND hFind = BluetoothFindFirstRadio(&btfrp, &hRadio);
// BluetoothGetDeviceInfo(hRadio, &pbtdi);
printf("Bluetooth test!");
BluetoothFindRadioClose(hFind);
return 0;
}
It seems that my issue was not 100% my code, but about how I was attempting to compile my code. After looking further into the documentation I read the line, "Link only to Bthproprs.lib, and avoid linking to Ilprops.lib." So, I don't fully understand why I would need to link, when I have a #pragma comment(lib, "Bthprops.lib"); but that is most likely due to my own ignorance. I did notice the answer on this post which helped clear up my ignorance of HOW to link the Bthproprs.lib library. So, my code didn't change, but my compile did, gcc bluetest.c -o test -lbthprops.
Now, to return something actually useful.

LNK 2019 while compiling main.c

I am just a beginner in C and Visual Studio and I have this weird error.
I declared a function in cipher.h and defined it in cipher.c (I have included cipher.h in cipher.c). I include cipher.h in main.c and used the function. But it gives me this error while compiling main.c:
unresolved external symbol test_encrypt referenced in function _main
Here are the codes:
cipher.h:
#pragma once
#include <stdio.h>
#include <stdbool.h>
void test_encrypt(char message[]);
cipher.c:
#include "cipher.h"
void test_encrypt(char message[])
{
message[0] = '0';
}
main.c:
#include <stdio.h>
#include "cipher.h"
int main(void)
{
// open a text file and read the text into an array called buffer
// the text is "54321"
test_encrypt(buffer);
printf(buffer);
}
Everything works fine if I remove the line that use test_encrypt function.
Thanks in advance.
Think about the C compilation stages.
First C sources are built into objects. Those are compiled files which are like building blocks of your final executable. When you call cipher in your main, the compiler looks at the included headers and see if it finds anything that matches it. Since you have defined the function prototype, the compiler knows that such function exists somewhere, but it does not know where, at this stage.
The main.o object will have a reference to cipher declared as "external". After this stage of compilation, it's the linker job to be sure that the symbols you have are somewhere. From here it looks either in the other object files or in some libraries, and if it can't find it anywhere, it throws the error you are seeing.
What I can imagine it's happening here is that you didn't specify "cipher.c" to be part of you VS project, hence "cipher.o" is not being built, resulting in the error from the linker.

'undefined reference to function' while trying to build a program with header that redefines function names

I'm having the exact same problem as a person that asked this question: How to hide the exported symbols name within a shared library
I decided to follow instructions given by Alexander (3rd answer) but after including a generated header to my main program in C, i get the error undefined reference to function
head.h
#define SecretFunc1 abab
application.c
#include <stdio.h>
#include "head.h"
int main(){
SecretFunc1();
return 0;
}
libdyn.c
#include <stdio.h>
int SecretFunc1(){
return 2
}
I've built the dynamic library into .so file, then after trying to build the app with:
gcc app.c -L<path> -ldyn -o sample
In function main undefined reference to abab
I don't really know what to do.
After (partial) preprocessing, your application.c would look like this:
#include <stdio.h>
int main(){
abab();
return 0;
}
This should, first of all, give you a warning, that abab is declared implicitly, which usually is not a good idea. You should declare the function (in a header file shared by application.c and libdyn.c):
int SecretFunc1(void);
When compiling to an object file, this object file will have a reference to the symbol abab.
After compiling libdyn.c to an object file, it will provide a symbol named SecretFunc1. Therefore, the linker will not match it to the reference abab in application.o.
You need to rename the function in all files using it, e.g. by including head.h in libdyn.c as well or better putting both the renaming macro and the declaration in a libdyn.h that is included in both libdyn.c and application.c.

string.h and stdlib.h functions give me the error: undefined reference to '...'

I'm modifing a c project and is the first time I'm tryng to use the stdlib.h and string.h libraries in my project. I'm working on MCUXpresso (IDE based on eclipse). This is my code:
#include <string.h>
#include <stdlib.h>
#include "config.h"
int number=100;
int n1,n2;
char test[5]="test";
char str[5];
extern void fntest(TTASKTABLE *ptrTaskTable)
{
itoa (number,str,10);
n1=strlen(test);
n2=atoi(test);
}
As you can see I've included the header files but the compiler give the errors: undefined reference to 'itoa' ; undefined reference to 'strlen' ; undefined reference to 'atoi'
And in my includes folder there is already (by default on my project) the folder containing the standard libraries.
I see the functions are used in some other files in the project... I can't understand why I've this error.
In the original code the functions are in a body function, I've corrected that.
Can you help me please?
finally I've solved my problem !
Ijust had to change the linker settings: project-->properties-->C/C++ Build-->settings-->MCU Linker-->general and change form No startup or default libs to Do not use standard start files and then no more errors!
I don't know if you have posted your actual code, but at this stage as you have uploaded its not going to compile.
#include <string.h>
#include <stdlib.h>
#include "config.h"
int number=100; // This is okay
int n1, n2; // This is okay
char test[5]="test"; // This is okay
char str[5]; // This is okay
itoa (number,str,10); // This is wrong
n1=strlen(test); // This is wrong
n2=atoi(test); // This is wrong
Whatever that I have appended with a comment // This is wrong is because, these needs to be in a function body.
Now since you already stated that,
I see the functions are used in some other files in the project..
I don't have to provide you with a way to implement itoa function.
Update:
Since now that you have added it into a function, the point that I talked about is fixed. Now, it should ideally compile, provided that there a valid definition of a itoa function in one of the header files that have been included.

Can I make a custom header file named "stdio.h"?

Can I make a custom header file named stdio.h and can use it in my program along with <stdio.h>?
C11 7.1.2p3:
If a file with the same name as one of the above < and > delimited sequences, not provided as part of the implementation, is placed in any of the standard places that are searched for included source files, the behavior is undefined.
The standard places then refers to 6.10.2p2:
searches a sequence of implementation-defined places for a header identified uniquely by the specified sequence between the < and > delimiters, and causes the replacement of that directive by the entire contents of the header. How the places are specified or the header identified is implementation-defined.
So the only guarantee given here is that if your stdio.h is not in an implementation-defined place for a searching a header, then the behaviour wouldn't be undefined. You can then include it with
#include "stdio.h"
However if you really intended that the file would be included with
#include <stdio.h>
then for the compiler to find it you need to place it in any of the standard places, and all bets are off.
However, in a freestanding - i.e. not hosted - execution environment. stdio.h might not be a standard header name so it might as well be perfectly OK there. Not that there is anything portable about the freestanding execution environment.
Thus, unless you specify more specifically what you're up to, we can only refer to the C standard and shrug. Having a source file named stdio.h isn't strictly conforming but it very much might be conforming, so YMMV.
As noted by Antti Haapala, it is explicitly described as undefined behavior to name a file stdio.h and put it in any of the directories where the compiler looks for include files.
Yet, by default, the compiler does not search for standard headers in the directory of the source file, but a command line argument of -I. can easily change this behavior.
Without this option and assuming you do not put your source files in the compiler's system directories, you could use the name stdio.h for an include file and include that with #include "stdio.h" without interfering with the standard header referred to in #include <stdio.h> (which might not even be a file at all).
You could go one step further into confusion-land by naming the source file itself stdio.h...
I you truly want to confuse the reader, name the source file a.out and compile with gcc -o stdio.h -x c a.out.
If you specify where in your file directory your custom "stdio.h" comes from (i.e. doing
#include "C:/ProgrammingC/stdio.h"
is probably fine, but
#include "stdio.h" //This only selects the standard include
//if there's no other stdio.h in the build directory
is risky, and
#include <stdio.h>
is definitely not what you want.
I've created a file named as stdio.h and main.c afterwards added this content to main.c to test out if it works properly.
#include "stdio.h"
#include <stdio.h>
int main()
{
testArea(); // this will use "stdio.h"
int test = 2;
printf("%d", test); // this will use <stdio.h>
return 0;
}
Program output:
1002 (100 from "stdio.h" and 2 from <stdio.h>)
Content of my stdio.h:
#include <stdio.h>
void testArea()
{
int abc = 100;
printf("%d", abc);
}
Surprise surprise, it does! Now, you should know that using "" means searching header file via file path. Meanwhile <> basically looks at the includes folder of the compiler.
So that, you can do that.
PS: If you're going to downvote, make an explanation so that I can learn what's wrong too. It just works fine for me.
Edit: Now, you can see that program knows what to call and what to do.
Bonus: If you try to add a same name function that exists in the file compiler will give you an error.
#include <stdio.h>
void testArea()
{
int abc = 100;
printf("%d", abc);
}
void printf()
{
}
Will return stdio.h:9:7: error: conflicting types for ‘printf’ as an example. You just should avoid using existing functions, but it's not restricted to same name header files. You just can't do it with any filename since the names are going to conflict.
Again, the usage of this is fine. There should be no problems at all.
Edit 2: I'm using Linux Mint 18.2.
Here is my gcc --version
gcc (Ubuntu 5.4.0-6ubuntu1~16.04.4) 5.4.0 20160609
Copyright (C) 2015 Free Software Foundation, Inc.
This is free software; see the source for copying conditions. There is NO
warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
And, here is how I compile my code:
duman#duman-pc ~/Desktop/Nuclear Test Zone $ gcc main.c -o test
duman#duman-pc ~/Desktop/Nuclear Test Zone $ ./test
Nothing fancy, and I don't really know what can cause undefined behaviour since my compiler won't allow usage of same name functions.
Edit 3: Just to see if anything related to name usage throws a warning I compiled the same code with ALL of these flags: https://stackoverflow.com/a/34971392/7735711 and there were none about the names.
That's the best I can do. Hopefully it helps you.

Resources