Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I properly export symbols into a windows DLL using MinGW?

Tags:

c++

mingw

dll

I am trying to create a C++ library that has one exposed function using MinGW.

I think I have read enough tutorials, looked around the internet, but nothing seems to work, the error is always the same. Undefined reference to the function.

Here is the library's header (findPoints.h):

#ifndef FIND_POINTS_H
#define FIND_POINTS_H

#ifdef BUILDING_FIND_POINTS_DLL
#define FIND_POINTS_DLL_PREFIX __declspec(dllexport)
#else
#define FIND_POINTS_DLL_PREFIX __declspec(dllimport)
#endif

#ifdef __cplusplus
extern "C" {
#endif

FIND_POINTS_DLL_PREFIX void findPoints(uint8_t* data, int height, int width, int* cx, int* cy, int* lx, int* ly, int* rx, int* ry, int* quality);

#ifdef __cplusplus
}
#endif

#endif 

Here is the function declaration in its source file (findPoints.h):

#include "findPoints.h" 

//...

void FIND_POINTS_DLL_PREFIX findPoints(uint8_t* data, int height, int width, int* cx, int* cy, int* lx, int* ly, int* rx, int* ry, int* quality) {
    std::thread worker(findDroplet, data, height, width, cx, cy, lx, ly, rx, ry, quality);
    worker.detach();
}

The file is about 1000 lines long (all are parts of the declaration of findDroplet, depending only on standard libraries), so I have omitted that, the error does not appear to be there anyway.

To verify it's correct, I include it in a main.cpp file. Although it compiles when I use:

gcc main.cpp findPoints.cpp -o findPoints.exe

I can't create a dll that would be usable (I need a dll). This is what I do:

g++ -c -O3 -DBUILDING_FIND_POINTS_DLL findPoints.cpp 
g++ -c main.cpp
g++ -shared -o findPoints.dll -Wl,--out-implib,libfindPoints.a
g++ -o findPoints.exe main.o -L. -lfindPoints

It fails with error message:

main.o:main.cpp:(.text+0x1d5): undefined reference to `_imp__findPoints'

I tried all kinds of permutations of prefixes, but nothing seems to work. Always fails to find findPoins, depending on prefixes it can have some prefixes or suffixes, but it is never there. I tried dlltool, but it never lists that function at all.

It appears like if the findPoints function from the cpp file was completely ignored, the error message remains the same if I change its name. They have the same signatures because otherwise compiling them together would not work.

EDIT: More research: I managed to create a dll library and an exe program that uses it using Visual Studio. It works (and crashes if the dll is absent). But if I try to use MingGW to compile the program and link the dll to it, the error remains the same. The problem is solved now, but at the cost of a heavy workaround. Still, I would like to know the answer because I don't like Visual Studio.

like image 948
Dugi Avatar asked Aug 01 '17 18:08

Dugi


People also ask

How do I see exported symbols in a DLL?

The winedump tool for interacting with DLL PE files. We can use the winedump command to display information about a PE file. A PE file stores its exported symbols in its export address table. The PE file then stores its export address table in the “export” section of the PE file.

What are DLL A files?

A DLL is a library that contains code and data that can be used by more than one program at the same time. For example, in Windows operating systems, the Comdlg32 DLL performs common dialog box related functions. Each program can use the functionality that is contained in this DLL to implement an Open dialog box.


1 Answers

When you create the DLL you're not passing any objects to g++.

Replace

g++ -shared -o findPoints.dll -Wl,--out-implib,libfindPoints.a

with

g++ -shared -o findPoints.dll findPoints.o -Wl,--out-implib,libfindPoints.a

in your build sequence.

like image 61
t0m Avatar answered Oct 21 '22 22:10

t0m