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);
...
Related
I would like to build a .dll filled with Lua bindings written in C compiled using VS 2017, but I don't seem to be having any luck, and the resources available to me are confusing and, by majority, outdated.
Here is what I've done.
I've already compiled lua from source and added it to my path so that I can lua.exe anything. This also created lua53.dll.
I've taken all of the .c and .h files of the lua source and added them to my VS project, along with one main.c which I am using to test. I added the .dll file as well, but only in the same way that I added the .c and .h files. I don't think it's doing anything.
Here's main.c:
#define LUA_LIB
#include "lua/lua.h"
#include "lua/lualib.h"
#include "lua/lauxlib.h"
#include "tg/tg.h"
static int lua_TG(lua_State *L) {
return 1;
}
static int lua_useTGHandle(lua_State *L) {
struct TGHandle *tgHandle = malloc(sizeof(struct TGHandle));
*tgHandle = TG();
lua_pushlightuserdata(L, tgHandle);
return 1;
}
static const luaL_Reg tglib[] = {
{"TG", lua_TG},
{"useTGHandle", lua_useTGHandle},
{NULL, NULL}
};
LUALIB_API int luaopen_libtg(lua_State* L) {
luaL_newlib(L, tglib);
return 1;
}
One function implemented, one not, but the lib should register.
I have changed the build type to a .dll, and I get the .dll generated without any errors, but when I try to use it in a Lua script I get:
%1 is not a valid Win32 application.
Surely I just have no clue what I'm doing. How would I just set up a lua-binding-building environment in VS2017?
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
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.
Is there an equivalent of the following on Windows?
#include <dlfcn.h>
#include <stdio.h>
void main_greeting(void)
{
printf("%s\n", "hello world");
}
void lib_func(void)
{
void (*greeting)(void) = dlsym(RTLD_MAIN_ONLY, "main_greeting");
greeting ? greeting() : printf("%s\n", dlerror());
}
int main(void)
{
lib_func();
return 0;
}
This is a short snippet, the real purpose is to call a function know to exist at a main process (main_greeting), from inside a function (lib_func) from a dynamic loaded library. The main process is not modifiable, and so cannot be rewritten to pass callbacks.
On Windows, executables and DLLs are of the same format (PE nowadays), so an executable can export functions too. GetProcAddress(GetModuleHandle(NULL),TEXT("main_greeting")) will do what you want if the function is exported from the executable. It's done by -Wl,-export-all-symbols for mingw GCC.
I believe there is no equivalent option for Microsoft's linker, so if you use their toolchain, you have to:
export every function with __declspec(dllexport) in source files,
or write a module definition file listing every exported function, passing it to linker,
or generate module definition file automatically.
e.g. In a static library I had
void function (void);
function();
And function() existed in the main application.
But If I build it as a DLL the linker complains that the function is undefined on the DLL.
Yes, but this is hackish.
In the dll :
typedef void(*funcPtr)(void);
// Declare a variable named "ptrFunction" which is a pointer to a function which takes void as parameter and returns void
funcPtr ptrFunction;
// setter for ptrFunction; will be called from the .exe
void DLL_EXPORT setFunction(funcPtr f){ptrFunction f;}
// You can now use function() through ptrFunction
foo(){
ptrFunction();
}
and you call setFunction from the .exe.
void function(){
// implementation here
}
int main(){
setFunction(&function); // now the dll knows the adress of function()
foo(); // calls foo() in dll, which calls function() in the .exe
....
}
Great, huh ? :/
You should probably refactor your code so that function() is in yet another DLL, but it depends.
Yes you can but I would strongly recommend against it if you don't have to. It's fiddly and it feels like you need to sort out your dependencies better.
To do it, you have to use LIB.EXE to create an import library from the object files of one binary before you actually link it; use this import library to link other binary and create an import library for the other binary; finally use the other library's import library to link the original binary.
E.g.
exe.c:
#include <stdio.h>
void __declspec(dllimport) dllfn(void);
void __declspec(dllexport) exefn(void)
{
puts("Hello, world!");
}
int main(void)
{
dllfn();
return 0;
}
Compiler with cl /c exe.c. exe.obj is created.
exe.def:
LIBRARY exe.exe
Create import library with lib /def:exe.def exe.obj. exe.lib and exe.exp are created.
dll.c:
void __declspec(dllimport) exefn(void);
void __declspec(dllexport) dllfn(void)
{
exefn();
}
Compile with cl /c dll.c. dll.obj is created.
Link DLL with link /dll dll.obj exe.lib. dll.dll, dll.lib and dll.exp are created.
Link EXE with link exe.obj dll.lib. exe.exe is created. (exe.lib and exe.exp are also recreated.)
Run exe, note the Hello, world! output.