Why does using curl_easy_init() output unusual error code? - c

I am currently learning C, using CLion on Windows, and as so I am starting off with a very simple program using cURL.
I have finally successfully included the library in my code using CMake as performed in this question:
How do I link dynamically built cmake files on Windows?
The code now builds without error.
The issue is, as soon as I write the curl_easy_init(), the program outputs with an unusual exit code not referenced in the cURL docs and print functions fail to output like normal.
#include <stdio.h>
#include <curl/curl.h>
int main(void) {
printf("Hello world!\n");
CURL *curl;
CURLcode res;
curl = curl_easy_init(); // Line that changes program
return 0;
}
Whenever that dreadful line is written, the program no longer outputs a happy old "Hello World!" with an exit code of zero, and instead, outputs this:
Process finished with exit code -1073741515 (0xC0000135)
What even is that exit code??
Any information is much appreciated.

0xC0000135 is "application not correctly initialized", which generally indicates that the loader cannot find a dll required by your application. Most probably you linked the libcurl import library, but the corresponding dll (libcurl.dll) cannot be found in the same directory of the executable and isn't in the global dll search paths. Make sure the dll is available when you launch your application, or link libcurl statically.

Related

DebugPrint pushes empty line (Serial connection)

Upon deciding to write a simple "Hello World!" program in EDK2,
I stumbled upon the following problem:
As I am using a serial connection for debugging, the output of the debug functions like DebugPrint successfully get redirected to my serial terminal (PuTTY in this case), well sort of.
After compiling an executing the following program inside an UEFI shell, I simply get
an empty line as a result.
But after executing the same binary again, the line gets successfully printed in all it's beauty.
This is the source code of the program i ran:
#include <Uefi.h>
#include <Library/DebugLib.h>
EFI_STATUS
efi_main(EFI_HANDLE ImageHandle,
EFI_SYSTEM_TABLE* SystemTable
)
{
DebugPrint(DEBUG_INFO, "Hello World!\n");
return EFI_SUCCESS;
}
Serial output:
Note: I linked my program against IoLib, SerialPortLib and DebugLib
What could be causing this issue?
After a lot of fiddling around I realised, that I manually specified the entry point to my main-function (efi_main), which should instead point to _ModuleEntryPoint when using the UefiDriverEntryPoint library from EDK2.
This solved my problem instantly :)

TCL: call TCL package while embedded in C

From this question I learnt that we can embed TCL in C as easy as the folloiwng
#include <stdio.h>
#include <tcl.h>
void main ()
{
Tcl_Interp *myinterp;
char *action = "set a [expr 5 * 8]; puts $a";
int status;
printf ("Your Program will run ... \n");
myinterp = Tcl_CreateInterp();
status = Tcl_Eval(myinterp,action);
printf ("Your Program has completed\n");
getch();
}
And to compile it, we need to define path to the tcl libraries:
gcc -o test.exe test.c -Ic:/tcl/include /mingw64/bin/tcl86.dll
My question is: If my tcl script is calling another package (for example: package require Img), How to include this package (for example "Img") in the created test.exe.
I am using mingw64 on windows to compile my C code, but when running the resulted test.exe, it gives me TCL error that {can't find package Img while executing "package require Img"}
BTW, I have Img is installed in and when I run my TCL script using tclsh, I have no errors.
You should extend the list in the global auto_path variable with the path to the location (i.e., the directory) of the extra libraries you want to be able to access.
Tcl_SetVar(interp, "::auto_path", "/path/to/directory", TCL_APPEND_VALUE | TCL_LIST_ELEMENT);
Do this after you create the interpreter but before you evaluate any scripts in it. This is safe against characters like spaces in the pathname. On Windows, you can use \ as a separator if you prefer. If you have multiple locations, put several calls to Tcl_SetVar() in. (How you work out the correct directory or directories is up to you; the value gets copied immediately.)

run a C program at startup [Red Pitaya]

I have a C program that needs to run when I turn on my machine (Red Pitaya).
the beginning of the program presented here:
//my_test program
#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include "redpitaya/rp.h"
int main(int argc, char **argv){
int jj=1;
while(1) {
printf("Ready for experiment number %i\n",jj);
int i, D;
int32_t TrigDly;
and so on...
the program is executable with a run.sh file called uri_test.sh, that contains the following:
cat /opt/redpitaya/fpga/fpga_0.94.bit>/dev/xdevcfg
LD_LIBRARY_PATH=/opt/redpitaya/lib ./my_test
both files are located in a directory under /root. the program is working perfectly when run manually on PuTTY terminal-
/RedPitaya/Examples/C/Uri# ./my_test
or
/RedPitaya/Examples/C/Uri# ./uri_test.sh
I tried to follow the solution presented here :
https://askubuntu.com/questions/9853/how-can-i-make-rc-local-run-on-startup
without success.
any suggestions? Thank you.
There are several ways to have a program running at startup, and it depends upon your init subsystem (are you using systemd or a SysV-style init?).
BTW, a source program in C is not a script and you generally compile it (using gcc -Wall -Wextra -g) into some executable. In your case, you probably want to set up its rpath at build time (in particular to avoid the LD_LIBRARY_PATH madness), perhaps by passing something like -Wl,-rpath,/opt/redpitaya/lib to your linking gcc command.
Perhaps a crontab(5) entry with #reboot could be enough.
Whatever way you are starting your program at startup time, it generally is the case that its stdin, stdout, stderr streams are redirected (e.g. to /dev/null, see null(4)) or not available. So it is likely that your printf output go nowhere. You might redirect stdout in your script, and I would recommend using syslog(3) in your C program, and logger(1) in your shell script (then look also into some *.log file under /var/log/). BTW, its environment is not the same as in some interactive shell (see environ(7)...), so your program is probably failing very early (perhaps at dynamic linking time, see ld-linux.so(8), since LD_LIBRARY_PATH might not be set to what you want it to be...).
You should consider handing program arguments in your C program (perhaps with getopt_long(3)) and might perhaps have some option (e.g. --daemonize) which would call daemon(3).
You certainly should read Advanced Linux Programming or something similar.
I recommend to first be able to successfully build then run some "hello-world" like program at startup which uses syslog(3). Later on, you could improve that program to make it work with your Red Pitaya thing.

extract library version from binary with CMake

I am writing a FindXXX.cmake script for an external C library. I would like my script to provide information about the library version. However, the library only provides this information in the form of a function that returns the version number as a string.
I thought I could extract the version number by having FindXXX.cmake compile the following C program on the fly:
#include <stdio.h>
#include "library.h"
int main() {
char version[256];
get_version(version);
puts(version);
return 0;
}
In order for this to work, CMake should compile and run the program above at configure time, and use the information it prints as the version identifier. I know how to do the latter (execute_process), and I almost know how to do the former: CheckCSourceRuns comes to mind, but I do not know how to capture the stdout of the generated executable.
TL;DR: is there a way to compile a program, run it and capture its stdout from CMake at generation time?
You may use try_run for that purpose (it is assumed that your source file is named as foo_get_version.c):
try_run(foo_run_result foo_compile_result
foo_try_run ${CMAKE_CURRENT_LIST_DIR}/foo_get_version.c
RUN_OUTPUT_VARIABLE foo_run_output)
if(NOT foo_compile_result)
# ... Failed to compile
endif()
if(NOT foo_run_result EQUAL "0")
# ... Failed to run
endif()
# Now 'foo_run_output' variable contains output of your program.
Note, that try_run isn't executed when cross-compiling. Instead, CMake expects that the user will set cache variables foo_run_result and foo_run_result__TRYRUN_OUTPUT.

run c program - stdio.h where do i get it?

Looking into learning C. As I understand it when I say #include <stdio.h> it grabs stdio.h from the default location...usually a directory inside your working directory called include. How do I actually get the file stdio.h? Do I need to download a bunch of .h files and move them from project to project inside the include directory? I did the following in a test.c file. I then ran make test and it outputted a binary. When I ran ./test I did not see hello print onto my screen. I thought I wasn't seeing output maybe because it doesn't find the stdio.h library. But then again if I remove the greater than or less than signs in stdio the compiler gives me an error. Any ideas?
I'm on a Mac running this from the command line. I am using: GNU Make 3.81. This program built for i386-apple-darwin10.0
#include <stdio.h>
main()
{
printf("hello");
}
Edit: I have updated my code to include a datatype for the main function and to return 0. I still get the same result...compiles without error and when I run the file ./test it doesn't print anything on screen.
#include <stdio.h>
int main()
{
printf("hello");
return 0;
}
Update:
If I add a \n inside of the printf it works! so this will work:
#include <stdio.h>
int main()
{
printf("hello\n");
return 0;
}
Your code should have preferably
printf("hello\n");
or
puts("hello");
If you want to know where does the standard header file <stdio.h> comes from, you could run your compiler with appropriate flags. If it is gcc, try compiling with
gcc -H -v -Wall hello.c -o hello
Pedantically, a standard header file is even not required to exist as a file; the standard permits an implementation which would process the #include <stdio.h> without accessing the file system (but e.g. by retrieving internal resources inside the compiler, or from a database...). Few compilers behave that way, most really access something in the file system.
If you didn't have the file, you'd get a compilation error.
My guess is the text was printed, but the console closed before you got the chance to see it.
Also, main returns an int, and you should return 0; to signal successful completion.
#include <header.h>, with angle brackets, searches in standard system locations, known to the compiler-- not in your project's subdirectories. In Unix systems (including your Mac, I believe), stdio.h is typically in /usr/include. If you use #include "header.h", you're searching subdirectories first and then the same places as with <header.h>.
But you don't need to find or copy the header to run your program. It is read at compilation time, so your ./test doesn't need it at all. Your program looks like it should have worked. Is it possible that you just typed "test", not "./test", and got the system command "test"? (Suggestion: Don't name your programs "test".)
Just going to leave this here : STILL! in 2018, December... Linux Mint 18.3
has no support for C development.
innocent / # cc ThoseSorts.c
ThoseSorts.c:1:19: fatal error: stdio.h: No such file or directory
compilation terminated.
innocent / # gcc ThoseSorts.c
ThoseSorts.c:1:19: fatal error: stdio.h: No such file or directory
compilation terminated.
innocent / # apt show libc6
(Abbreviated)::
Package: libc6
Version: 2.23-0ubuntu10
Priority: required
Section: libs
Source: glibc
Origin: Ubuntu
Installed-Size: 11.2 MB
Depends: libgcc1
Homepage: http://www.gnu.org/software/libc/libc.html
Description: GNU C Library: Shared libraries
Contains the standard libraries that are used by nearly all programs on
the system. This package includes shared versions of the standard C library
and the standard math library, as well as many others.
innocent / # apt-get install libc6-dev libc-dev
So, magic... and a minute later they are all installed on the
computer and then things work as they should.
Not all distros bundle up all the C support libs in each ISO.
Hunh.
hardlyinnocent / # gcc ThoseSorts.c
hardlyinnocent / # ./a.out
20
18
17
16
... ... ...

Resources