I use freecommandlinetools compiler bcc32. I need to use third party dll in my program. I'd prefer not to call LoadLibrary and GetProcAddress, but rather to link the dll in my program to call the dll functions directly.
#include "somelibrary.h"
int main() {
somefunction(); // defined in somelibrary.dll
}
I see unresolved externals in attempt to compile. How to convince the linker to link with the somelibrary.dll?
You must create a .lib in order to link the dll directly.
Supposing your dll is user32.dll :
implib -a -c -f user32.lib user32.dll
Will create user32.lib with all the symbols of user32.dll. Then link your project with user32.lib instead of user32.dll.
You can use the impdef.exe command to see the symbols exported by the dll. If these symbols already start with an underscore '_', you can omit the -a in the implib command.
Related
I remember finding *.a library that doesn't contain any object but instead a list libraries (as a plain text?), something like: -liconv -lm
So that when gcc encounter it, both library will be searched for linking.
Is there such trick? pretty sure it was working that time, but I don't know how to make it now.
Is your linker from binutils? binutils ld supports .a files as implicit linker scripts:
If you specify a linker input file which the linker can not recognize as an object file or an archive file, it will try to read the file as a linker script. If the file can not be parsed as a linker script, the linker will report an error.
A linker script does not have to be complicated, it can be as simple as this (for glibc's libc.so):
/* GNU ld script. */
OUTPUT_FORMAT(elf64-x86-64)
GROUP ( …/libc.so.6 …/libc_nonshared.a AS_NEEDED ( …/ld-linux-x86-64.so.2 ) )
Or you can just use INPUT to delegate things to ld:
If you use ‘INPUT (-lfile)’, ld will transform the name to libfile.a, as with the command line argument ‘-l’.
I have gone through all the solutions on StackOverflow as well as Ask Ubuntu.
I have a Go program:
package main
import "C"
//export Getint
func Getint() int {
return 2
}
func main() {}
and I have generated .so file for the same with name t.so and header filet.h`
Now I would like to use this function in my C program.
I have written the code but I don't know how to execute it.
#include <stdio.h>
#include <t.h>
int main()
{
int a;
a=Getint();
printf("number : %d",a);
return 0;
}
When I execute it with
gcc c.c t.so
it generates a.out file
but at the time of running a.out with ./a.out it gives an error:
./a.out
Error while loading shared libraries: t.so: can not open shared object file: no such file or directory exists.
then I tried with:
gcc -c c.c -l t.so
So it generates c.o file and it is not executable.
You should use the linker option -rpath, which tells the linker to add information in the executable program where to find runtime libraries like your .so file.
This can be done using the GCC option -Wl which instructs the GCC frontend program to pass an option to the linker:
$ gcc c.c t.so -Wl,-rpath=$(pwd)
This will pass -rpath=$(pwd) to the linker, and $(pwd) causes the shell to call the pwd command to return the current directory.
As long as you don't move the library the program should work.
You can use the environment variable LD_LIBRARY_PATH too, but it's not recommended.
Most probably your loader cannot find the library. Try to put the path to the directory where the libarry is located to LD_LIBRARY_PATH prior to run your binary.
export LD_LIBRARY_PATH=/path/to/my/library
./a.out
.so files are shared object, meaning object that are available to all applications that need them.. that is, shared. Due to this characteristics, they need to be stored in a well known place. Also, they need to be indexed by the dynamic linker.
In linux for instance you typically have a file /etc/ld.so.conf where all directories where shared object are automatically read from are stored
So your options are:
Put your shared object file in a well known place
Put your shared object file in a place of your choice and let the dynamic linker know about it: in linux you can modify ld.so.conf and run ldconfig to update ld indexes
As other suggested write the path of your .so in the env variable LD_LIBRARY_PATH (since dynamic linker reads it before running your application). This must be done at each environment creation
As other suggested use -rpath when compiling. Note that in this way you cannot move your .so file after the compilation
Personally I prefer installing the .so file in a system library path
You should use LD_LIBRARY_PATH to let the dynamic linker find your shared library in the list. Syntax is similar to PATH a list of directories separted by :.
On OSX this environment variable is called DYLD_LIBRARY_PATH.
I have a problem with linking together different libraries using it in one executable project.
Let's say Project A contains a function named foo(); It is compiled as a static library.
Project B contains a function named bar(), includes a header from A and compiled as a shared library with -Wl,--whole-archive libA.a -Wl,--no-whole-archive flags. libB.so was moved to /usr/lib.
Now, project C includes B.h, calls bar(), but wasn't compiled due to the reason of undefined reference to foo() function, which was defined in project A.
nm libB.so says:
U foo
I am using gcc, the programming language is C, the IDE is Eclipse CDT.
Is anyone who has an idea or tip to solve this problem?
Thank you.
Thanks to Icarus3 for his contribution, the problem is restricted.
Some functions in ProjectA used restrict keyword, thus it was compiled with -std=gnu99. It turns out that eliminating this keyword from the code and the -std=gnu99 from the compiling command eventually solved the problem.
When I link a library such as libm in with ld, I need to drop the lib prefix. What if the file does not follow this naming convention? Is there a way to link it other than renaming the file?
You can have the linker search for a library named without the lib prefix:
gcc main.o -L/path/to/foo -l:foo.a
This is especially useful in environments where a list of libraries is specified and the -l flag is prepended later (eg some makefiles or eclipse CDT)
You can link against any library, e.g. foo.a, by specifying full path to it on the link line:
gcc main.o /path/to/foo.a
What you lose with non-standard library name is the ability for the linker to search for it, e.g. this will not work:
gcc main.o -L/path/to foo.a
You can avoid that lack of search by using -l:foo.a syntax:
gcc main.o -L/path/one -L/path/two -l:foo.a
When I link a library such as libm in with ld
Note that in general you should not link anything with ld. Use the compiler driver instead -- it adds objects and libraries to the link line that are required for correct result.
Like the question says: We are building on Linux using the GNU linker, and on Solaris using the solaris ld. GNU ld supports the --export-dynamic flag, which:
When creating a dynamically linked executable, add all symbols to the dynamic
symbol table. The dynamic symbol table is the set of symbols which are visible
from dynamic objects at run time.
What is the equivalent to this flag using the solaris linker? Is there an equivalent?
The Sun Studio linker (ld), by default, exports all symbols.
You can find the complete reference for the Sun linker on docs.sun.com.
Search for the "Linker and Libraries Guide".
By "all symbols" you mean all global symbols, right? C file-static symbols
are not promoted to global right? I don't think that would work.