Creating a DLL in GCC or Cygwin? - c

I need help to compile a script ("iterator.c") into a DLL. I can't use VS2010 since it does not support the features added to C in the C99 standard (I'm using "complex.h" but VB doesn't support it).
I've been looking for a substitute but all I've found is GCC which I don't know how to install/use (really, I've spent like half an hour reading through the documentation and I don't even understand how am I supposed to install it), and Cygwin, which I've already installed but I don't know how to use either. Also, I've installed MinGW but I think it's the same as Cygwin more or less, and I still don't know how to make a DLL.
It's not like I've been all lazy and haven't even tried it, it's just that these compilers aren't like nothing I've ever used before (mostly Python IDLE and Visual Studio, which make things pretty easy for you). I'm kind of lost.
Could someone give me some advice on how to use this tools to make a DLL that I can access from another script? It is really important.
Thank you in advance.

You must place __declspec(dllexport) in front of the method you wish to export such as, you could #define this to max it easier
EXPORT_DLL void hello() { ... }
To compile the dll use
gcc -c -mno-cygwin mydll.c
gcc -shared -o mydll.dll mydll.o -Wl,--out-implib,libmylib.dll.a
then to attach
gcc -o myexe.exe test.o mydll.dll
EDIT: Forgot the most important piece, you need to make a mydll.h file to include your method definition so the compiler knows to reserve a spot for the linker to fill in later on. It's as simple as
#ifndef MYDLL_H
#define MYDLL_H
extern "C" __declspec(dllexport)
#define EXPORT_DLL __declspec(dllexport)
EXPORT_DLL void hello();
#endif

Related

Can you have multiple DLLs with common exports/ordinals and exchange at run-time?

I am trying to create a couple of Win32 64-bit DLLs (Windows 10) which have different implementations but consistent symbol exports. The aim for this is that one would link with whichever one at build time but have the option at deployment to install either DLL and correctly run with that. I have achieved this straightforwardly on Linux where I am much more comfortable and familiar with run-time linking. But on Windows, I have not yet managed this and I am wondering if this is possible at all. I am trying this using both VS2010 and VS2019.
Suppose I have two libraries blah_legacy.dll and blah_modern.dll. They both export 6 symbols which are the interface to using the library, e.g. blah_open, blah_read, blah_write, blah_close, blah_control, blah_status.
I can link with the import library for either blah implementation and a test program calling each symbol loads and executes correctly with the corresponding blah DLL.
However, I cannot yet switch the DLLs at run time. For example, should I actually be able to link with blah-legacy.lib and then run with blah-modern.dll if I rename it to blah-legacy.dll? (Or vice-versa.)
I already got around basic file-naming issues and ensured the DLL needed can actually be found. I still got the application failed to start (0x22).
I used "objdump -xs" on the DLLs and noticed the order of symbols and their ordinals are different. So I created a .def file and ensured that the exported symbols match in number, names and in ordinals. Still nothing - the same error occurs.
There's still something to this I clearly have not figured out and would appreciate some guidance. Is this actually possible? Where do I start to look (which tools) to figure out what step to take next.
Yes.
I don't use Visual Studio much, but this is the kind of thing that happens all the time if you use MSYS2, and install some MinGW packages, and update them.
Here's what I mean by that: MSYS2 is an open source software distribution for Windows that, among other things, provides a bunch of native Windows software packages. The package manager (pacman) let's you choose which packages to have in your system, and it downloads DLLs and EXEs that were created by the MSYS2 developers. When an MSYS2 developer updates a library, you can download the updated library package, and all the other packages using that library will automatically start using the new DLL. Usually there is no issue with that because the new library version will be ABI-compatible with the old library version.
You do not need to use LoadLibrary or otherwise mess up your source code; the linker and the operating system should be able to take care of this for you.
Example
Here is a minimal example I threw together with MSYS2 showing how this can work.
The file foo_legacy.c represents your legacy DLL. I added some extra symbols so it wouldn't be too similar to the modern DLL.
__declspec(dllexport) int eoo() {
return 0;
}
__declspec(dllexport) const char * foo_name() {
return "legacy";
}
__declspec(dllexport) int foo_version() {
return 1;
}
__declspec(dllexport) int goo() {
return 0;
}
The file foo_modern.c represents the modern implementation:
__declspec(dllexport) const char * foo_name(void);
__declspec(dllexport) int foo_version(void);
int foo_version() {
return 2;
}
const char * foo_name() {
return "modern";
}
The file main.c represents an application using the foo API:
#include <stdio.h>
__declspec(dllimport) const char * foo_name(void);
__declspec(dllimport) int foo_version(void);
int main()
{
printf("%s %d\n", foo_name(), foo_version());
}
My build.sh file is a Bash script that builds and tests everything:
#!/usr/bin/bash
set -uex
gcc -Wall foo_legacy.c -shared -o foo_legacy.dll
gcc -Wall foo_modern.c -shared -o foo_modern.dll
gcc -Wall -c main.c -I. -o main.o
gcc main.o foo_legacy.dll -o main.exe
./main.exe # output: "legacy 1"
mv foo_modern.dll foo_legacy.dll
./main.exe # output: "modern 2"
rm foo_legacy.dll
./main.exe # fails because foo_legacy.dll is not found
The build script runs main.exe three different times, showing that it can either use the legacy DLL, or use the modern DLL, or fail, depending on what was installed in foo_legacy.dll.

How can I link a program to two libraries with the same function name but different implementations?

I'm writing a program using libraries foo1.a and foo2.a.
Inside foo2.a, it uses foo3.a, which implements a function funcfoo. But foo1.a contains the same function that implements its own funcfoo. My main program wants to use funcfoo from foo1.a, and some other functions from foo2.a, while also makes sure that foo2.a only uses funcfoo from foo3.a.
Is there anyway I can enforce this to happen?
Short answer : you can't
Long answer : you still can't because name (like function name as well as global variable or enum name ... any name) have to be unique across your binary[1]
but
there is maybe action you can do.
If you own the source code of any library involved in this mess, make a complete new library with the same stuff but renamed.
Basically, i say "make a new major version of you library, since you will change the function name present in the library, thus breaking the retro-compatibility".
If you library is "foo1.a" containing the function "min", then make a "foo2.a" with "foo2_min" function.
It's usually a good pratice to prefix/suffix your internal function (be it in a library or directly in your binary) with something. Like if your company name is "My Little Pony", "MLP_" sound a good prefix (do a google search, just in case).
That's what user694733 said in the comment.
If you're using an IDE, then it should be easy and quick to do so with the "rename refactoring" feature.
I advise to do the most renaming possible in order to avoid further scenario like the one your stuck with now.
You don't have the source code, but the library licence allow you to modify it.
If it's format is open (like a good old so), you can use objcopy.
I read it can do that, but I never do it myself so .... good luck
If it's a close format, either you have the documentation about it and you have to do a lot of work, or you're completly stuck.
A third party own the code source, and/or the library licence don't allow you to modify it
If it's a third party library, maybe your company has subscribed to his support, so you better contact them directly.
.
As far as I know, there is no possibility to "encapsulate" a library into a "spacename" nativly in C.
I hope this answer an help, and I hope it's accurate and complete.
[1] Well, this is not completly rigth as you can create a local variable with a global variable's name, and this will compile and run. In the local context, it's the local variable that will be used. gcc can warn about this kind of scenario with -Wshadow option.
But unless you're doing some shady hack, this situation is usually something that you want to avoid.
Most linkers obey the order of the libraries as you provide them on the command line. If you link your program first with "foo1.a", it will resolve the references of funcfoo in your program with the implemention of "foo1.a". Place "foo2.a" second, which will leave an open reference to funcfoo. With "foo3.a" placed third, this will be resolved with the second implementation.
EDIT 1:
I'm afraid that I was wrong. A quick check (just before going to sleep) revealed that when "foo2.a" is linked, the reference to funcfoo is resolved with the implementation of the already loaded "foo1.a". :-(
I will do some more research, but please don't hold your breath.
EDIT 2:
OK, it took some time, but with the help of "objcopy" is works as proposed. You can use its option --redefine-sym old=new to "rename" symbols even in a library.
I have prepared a small example to follow the steps as a prove of concept. In the real project, the libraries are already built, so just the last commands of the shown list are needed.
Let's start with the main source:
#include "foo1.h"
#include "foo2.h"
int main(void) {
funcfoo();
funcbar();
return 0;
}
It includes the following header files, first "foo1.h" and second "foo2.h":
#ifndef FOO1_H
#define FOO1_H
void funcfoo(void);
#endif
#ifndef FOO2_H
#define FOO2_H
void funcbar(void);
#endif
Of course there are implementations of both, again first "foo1.c" and second "foo2.c":
#include <stdio.h>
#include "foo1.h"
void funcfoo(void) {
puts("funcfoo() in foo1");
}
#include "foo2.h"
#include "foo3.h"
void funcbar(void) {
funcfoo();
}
The third library "foo3" implements the same function as "foo1", first the header file and then the implementation file:
#ifndef FOO3_H
#define FOO3_H
void funcfoo(void);
#endif
#include <stdio.h>
#include "foo3.h"
void funcfoo(void) {
puts("funcfoo() in foo3");
}
These are the commands to build the application:
gcc -c -Wall -Wextra foo1.c -o foo1.o
ar cr libfoo1.a foo1.o
gcc -c -Wall -Wextra foo2.c -o foo2.o
ar cr libfoo2.a foo2.o
gcc -c -Wall -Wextra foo3.c -o foo3.o
ar cr libfoo3.a foo3.o
# In the real prject, only the following steps are needed:
gcc -c -Wall -Wextra main.c -o main.o
objcopy --redefine-sym funcfoo=funcfoo2 libfoo2.a libfoo2n.a
objcopy --redefine-sym funcfoo=funcfoo2 libfoo3.a libfoo3n.a
gcc main.o -L. -lfoo1 -lfoo2n -lfoo3n -o app
As you can see, the tool "objcopy" of the common "binutils" is used to redefine the name of the conflicting function from funcfoo to funcfoo2. I also let it create a new output library to save the original.
And when run, the application prints:
funcfoo() in foo1
funcfoo() in foo3

How to include <lua.h>?

When you #include files with <>, the compiler searcher for the headers in a certain location(s). Where am I supposed to keep the lua files for that to work? I guess I know where all(?) of gcc's .h files are at. Or do I have to keep them in the same project folder and do #include "lua.h" instead? I assume I should use whatever is in LuaDist instead of the binaries, since it's not compiled.
(I'm using Windows if it's needed to know that)
Edit: This is probably useless for Windows, sorry. If anyone running Linux/BSD/macOS/Solaris/etc. comes across this in the future, though:
There should be a pkg-config file available for Lua which will tell you exactly what flags you need. For Lua 5.1 (the version I see on Fedora 28), it's lua-5.1. So, to compile:
cc … `pkg-config --cflags --libs lua-5.1`

Call method from source file in another directory

I have a newbie question about the C programming language. I have looked around to find the answer in similar questions but I failed to figure it out.
Assume a simple project consisting of two dirs: src and test. The source and header files are defined by src/main.c, test/foo.h and test/foo.c.
src/main.c:
#include "../test/foo.h"
int main (void) {
int a = VAR; /* works, recognizes declared macro */
some_function(a); /* doesn't work, "undefined reference" */
}
test/foo.h:
#ifndef FOO_H
#define FOO_H
void some_function(int a);
#define VAR 2;
#endif
test/foo.c (redundant but to be complete):
#include "foo.h"
#include <stdlib.h>
void some_function(int a) {
printf("%d", ++a);
}
I created the project in Eclipse and I also compile with it, I figured it wasn't a linking error since the macro gets recognized but the method is not callable.
The reason why I'm using different directories is because I have a lot of files and would like my test code to be separate from my main source code. Note that src and test have the same parent directory.
Any ideas what's going on here? Am I missing something very obvious?
Any help would be much appreciated, thanks in advance!
edit: I'm working on a (Debian) Linux machine and Eclipse uses the gcc compiler.
edit2: Thanks to H2CO3's answer I learned it is indeed a linking error. Since compiling and linking manually every time is quite an overhead, I was wondering if anyone knows how to teach Eclipse to link executables from different directories?
--------------------- SOLUTION ---------------------
edit3: Lol the solution was very easy after all, all I had to do was create a "new source folder" rather than a "new folder". I feel stupid but thanks to you all for replying, H2CO3 in particular!
I figured it wasn't a linking error since the macro gets recognized but the method is not callable.
Non sequitur. Macros are expanded in the preprocessing phase. (And as such, they have nothing to do with linkage at all.) You do have a linker error.
What you have to do is compile both files then link them together, so something like this should work:
gcc -Wall -o dir_one/foo.o dir_one/foo.c
gcc -Wall -o dir_two/bar.o dir_two/bar.c
gcc -o my_program dir_one/foo.o dir_two/bar.o
Also, read this SO question/answer and/or this article to understand how the steps of the compilation process work together. (These are almost the same for C and C++, it's only the name mangling that usually differs.)

Load DLL Library

Is it possible to load a DLL with C and use its functions?
I am new in C, and I am trying to search some good references on the internet for this; but I can't find any.
Any help would be appreciated!
I am using GNU GCC in Code::Blocks on Windows 7, 64 Bit.
HMODULE hModule = LoadLibrary(<dll file name>) followed by GetProcAddress(hModule, <function name>) will do this job using the WinAPI.
An example could be found here.
I think you should investigate the LoadLibrary function.
http://msdn.microsoft.com/en-us/library/ms684175.aspx
Loads the specified module into the address space of the calling process. The specified module may cause other modules to be loaded.
Building a DLL using MinGW, here are some instructions:
First, you need to mark your functions for export, so they can be used by callers of the DLL. To do this, modify them so they look like (for example)
__declspec( dllexport ) int add2(int num){
return num + 2;
}
then, assuming your functions are in a file called funcs.c, you can compile them:
gcc -shared -o mylib.dll funcs.c
The -shared flag tells gcc to create a DLL.
For a free IDE which will automate all the flags etc. needed to build DLLs, take a look at the excellent Code::Blocks, which works very well with MinGW.
Also, see the article Creating a MinGW DLL for Use with Visual Basic on the MinGW Wiki.

Resources