I'm new to this site & not highly experienced in C,so pl pardon any mistakes I might commit unknowingly.
Ok,so I've got two files in C, one containing a function, & other one using that function.I think I'll need to create a header file for it,but I somehow cannot make it & need help.
here's file 1 :
#include<stdio.h>
int tempc=25,tempf;
int c2f(int c);
void main()
{
tempf=c2f(tempc);
printf("Celsius = %d,Farenheit=%d \n",tempc,tempf);
}
int c2f(int c)
{
int f;
f=9*c/5 + 32;
return f;
}
Here's file 2:
#include<stdio.h>
int tempc=25,tempf;
extern int c2f(int c);
void extern show(void);
void main()
{
tempf=c2f(tempc);
show();
}
The main question comes here. you might as well be thinking about the show function.
Actually, I'm asked to convert f1 into .asm file (using tcc -S f1.c) then add a module for show fn using assembly language, create .obj file of the .asm file, & with .obj file of f2, I've to put them in project & then build all to create .exe file.But I believe if I can simply run the program using 2 files as .c(ie with header part solved) I can do the rest.
One last question is, instead of creating header I'm wanting to do above, is it possible to keep these two files as they are, & create a header file-> make it .obj & add it to the project & build ?
A Sincere thanks to whoever tries to help.
A header file is meant to be used as a mechanism to "expose" functions to other C modules. For instance, you define a c2f() function in c2f.c and then create a prototype (essentially just a placeholder) in c2f.h. The prototype in c2f.h would look like the following:
int c2f(int c); /* Note the semicolon */
It shouldn't matter if the implementation of c2f() is in an assembly or c file. The header file simply allows C modules to make calls to c2f(). This is because you are providing the linker information to find the actual implementation of a function. The linker will then match all calls to that function to the actual address of the implementation. So, to use c2f just reference c2f.h in the file that is using it:
/* main.c */
#include "c2f.h"
...
You need to put c2f in a header and source files as such:
c2f.h:
int c2f(int c);
c2f.c:
int c2f(int c) {
return 9*c/5 + 32;
}
then compile that so you have a c2f.o file, include c2f.h in your two main() files that use it and linktheir compilation to the c2f.o file.
Related
Is it possible to execute C code in a C program? For instance when reading input from the user.
There's nothing built in to do this.
This simplest thing to do is save the given code to a separate file, invoke GCC as a separate process to compile the code, then run the compiled code in a new process.
Relatively easy: write C code to temporary file, invoke cc on temporary file to create shared library, use dlopen to load in and call functions in shared library
Harder: write C code to temporary file, invoke cc on temporary file to create conventional .o file, write your own dynamic linker to to load in and call functions in .o file
Harder: write a C interpreter to interpret C code directly
If you're targetting x86/ARM and Unix/Linux, you might find libtcc of use:
#include <libtcc.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
TCCState *s = tcc_new();
tcc_set_output_type(s, TCC_OUTPUT_MEMORY);
if (tcc_compile_string(s,
"#include <stdio.h>\n"
"void hello(void) {\n"
" printf(\"Hello world\\n\");\n"
"}\n"
) != 0)
{
fprintf(stderr, "Failed to compile the code\n");
exit(2);
}
tcc_relocate(s, TCC_RELOCATE_AUTO);
void (*hello)(void) = tcc_get_symbol(s, "hello");
hello();
}
I have a 218KB .dll and a 596KB .so file, both with identical names. I want to link to the .dll to avoid the "unresolved external symbol" error that the linker returns, but I can't find a way to link to the DLL file.
According to this Pelles C forum topic, I need to use the .def file to create a .lib... but I don't have a .def file. This forum topic shows how to use polink to create a .lib from the command line, so I ran polink /? to get some more options. I noticed a /MAKEDEF option, but running this with both the .dll and the .so gives a "No library file specified" fatal error.
I have been trying to do this for three hours, and am out of ideas. I have got to the point where my web searches turn up my own help-requests. There must be a way to do this... How can I link to a .dll?
With information found in the header #include and your details, here is a way to replace the missing function by calling them dynamically from your software.
1- the following prototype is in #include :
typedef float (* XPLMFlightLoop_f)(float inElapsedSinceLastCall, float inElapsedTimeSinceLastFlightLoop, int inCounter, void * inRefcon);
2- some const that you can fill as needed:
const char *sDllPathName = "<Your XPLM_API DLL>.dll";
const char *sXPLMRegisterFlightLoopCallbackName = "XPLMRegisterFlightLoopCallback";
In order to confirm the sXPLMRegisterFlightLoopCallbackName, you can
use the freeware Dependency Walker and check name and format of
the exported functions.
3- declare the prototype of the external function:
Be aware to the calling convention __cdecl or __stdcall
In the current case, the keyword XPLM_API is defined in the XPLMDefs.h as follow:
#define XPLM_API __declspec(dllexport) // meaning __cdecl calling convention
typedef void (__cdecl *XPLMRegisterFlightLoopCallback_PROC)(XPLMFlightLoop_f, float, void *);
4- clone the function to call it in your software:
#include <windows.h>
void XPLMRegisterFlightLoopCallback(XPLMFlightLoop_f inFlightLoop, float inInterval, void * inRefcon)
{
HINSTANCE hInstDLL;
XPLMRegisterFlightLoopCallback_PROC pMyDynamicProc = NULL;
// Load your DLL in memory
hInstDLL = LoadLibrary(sDllPathName);
if (hInstDLL!=NULL)
{
// Search for the XPLM Function
pMyDynamicProc = (XPLMRegisterFlightLoopCallback_PROC) GetProcAddress(hInstDLL, sXPLMRegisterFlightLoopCallbackName);
if (pMyDynamicProc != NULL)
{
// Call the XPLM Function with the orignal parameter
(pMyDynamicProc)(inFlightLoop,inInterval,inRefcon);
return;
}
}
// Do something when DLL is missing or function not found
}
5- just add your described call:
...
XPLMRegisterFlightLoopCallback(callbackfunction, 0, NULL);
...
Can a program be written without main() function?
I have written this code and saved a filename as withoutmain.c
and getting an error as
undefined reference to 'WinMain#16'"
My code
#include<stdio.h>
#include<windows.h>
extern void _exit(register int code);
_start(){
int retval;
retval=myFunc();
_exit(retval);
}
int myFunc(void){
printf("Hiii Pratishtha");
return 0;
}
Please provide me the solution of this problem and also the proper memory construction of code and what is happening at the compiler end of this program.
Thank you!
Can a program be written without main() function?
Yes there can be a C program without a main function.
I would suggest two solutions.......
1) Using a macro that defines main
#include<stdio.h>
#include<windows.h>
#define _start main
extern void _exit(register int code);
int myFunc(void){
printf("Hiii Pratishtha");
return 0;
}
int _start(){
int retval;
retval=myFunc();
_exit(retval);
}
2) Using Entry Point (Assuming you are using visual studio)
To set this linker option in the Visual Studio development environment
/ENTRY:function
A function that specifies a user-defined starting address for an .exe file or DLL.
Open the project's Property Pages dialog box. For details, see
Setting Visual C++ Project Properties.
LClick the Linker folder.
Click the Advanced property page.
Modify the Entry Point property.
OR
if you are using gcc then
-Wl,-e_start
the -Wl,... thing passes arguments to the linker, and the linker takes a -e argument to set the entry function
First things first, I am very new to C programming and the whole idea of compilation, so I would really appreciate some very straightforward and step-by-step guidance on this.
Here is my problem: I am trying to write some C code that I can dyn.load into R to speed up my R task. My C code would involve some very complex matrix operation that is only available in an external library with the header file "matrix.h" and the static library file "matrix.lib". It would also make use of some basic R header files such as "Rdefines.h", etc. The files "matrix.h" and "matrix.lib" are located at C:\lcc\include and C:\lcc\lib, respectively. Here is a sample test C code:
#include <Rmath.h>
#include <R.h>
#include <Rdefines.h>
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
#include <matrix.h>
void foo(double *cdegree, double *fdegree, int *size) {
int i;
for(i=0; i<*size; i++) {
cdegree[i] = 5.0/9.0*(fdegree[i]-32.0);
}
}
As you can see, this is simple code converting Fahrenheit to Celsius. Although the test code does not make use of anything in the matrix library, the goal here is to be able to include both the R header files and matrix.h from the external library. If I try R CMD SHLIB this C code I get the "no such file or directory" error for trying to include "matrix.h". How can I tell R to compile this with the external library? Everything is done on a Windows 8.1 X64 system.
Honestly, you will find it much easier if you start exploring Rcpp. Here is a link to introduce you to Rcpp. There are many examples to be found throughout the documentation.
f2c.cpp
#include <Rcpp.h>
// [[Rcpp::export]]
void foo(Rcpp::NumericVector fdegree, Rcpp::NumericVector cdegree, int size){
int i;
for(i=0; i < size; i++){
cdegree[i] = 5.0/9.0*(fdegree[i]-32.0);
}
}
R code
library(Rcpp)
sourceCpp("f2c.cpp")
fdegree <- c(98.6, 212, 32)
cdegree <- c(0,0,0)
foo(fdegree, cdegree, length(fdegree))
cdegree
[1] 37 100 0
Naturally this makes some assumptions but it demonstrates how you can quickly use some C code and not fiddle with all the R headers and SHLIB.
Regarding your concern to use some external headers, just simply set the PKG_CXXFLAGS environmental variable to the location of your header(s).
Sys.setenv("PKG_CXXFLAGS" = '-I"path/to/headers"')
followed by the same compilation.
sourceCpp("f2c.cpp")
However, it should be noted that if you are doing more than a few of these functions you should build a package with Rcpp and provide an appropriate Makevars file. You can find further information on Rcpp package development here.
I am working with some code which has the following style:
int
add5 (int x) {
return x+5;
}
In other words, the return value type of the function is written right above the function's name. Because of that, ctags is not recognizing these functions and causing me a terrible headache. Does someone know how to get ctags to handle this case?
EDIT: ctags can recognize the function names on .c files but what I need is ctags to recognize the function names on .h files. On the .h files I have things such as:
int
add5 (int);
and there ctags does not recognize add5.
You have to tell ctags to search for prototypes of functions. It is done with --<LANG>-kinds option.
So, run following command:
ctags --c-kinds=+p *
And it will add the declaration to the tags file, as you can see in the output of my test:
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert#users.sourceforge.net/
!_TAG_PROGRAM_NAME Exuberant Ctags //
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
!_TAG_PROGRAM_VERSION 5.8 //
add5 add.h /^add5 (int);$/;" p
It sounds to me like ctags is recognizing the function but not finding its declaration.
In fact, if you create this function in a header file:
int
plus(int a,int b) {
return a+b;
}
ctags can find it.