Author Topic: [SOLVED] Using a DLL  (Read 14361 times)

Offline TheLastArrived

  • Single posting newcomer
  • *
  • Posts: 9
[SOLVED] Using a DLL
« on: May 12, 2008, 05:00:42 pm »
Hello all,
 I don't know if this is the right place so I apologize if it's not.

I've to write an application that uses function from a dll but when I try to build a
Code
undefined reference to `_Z11TOpenDesignllPKcP10DbxContext@16'|
error message appears.

I've tried to tell C::B where to find the function but without success.

Any hints?
« Last Edit: May 14, 2008, 11:25:02 am by TheLastArrived »

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: Using a DLL
« Reply #1 on: May 12, 2008, 05:53:33 pm »
Too little information, but these are general things that can go wrong:
1. Name mangling may bite you if you use C++. Most DLLs export C functions, try using extern "C". Unless you forgot to link the library, this is the most common cause of symbol-related problems.
2. You should add the import library (if you use MinGW you can also direcly link to a DLL) to the linker's "link library" field
3. Name rape may affect you if you have Windows headers or something similarly abusive (wxWidgets) included. Sometimes, you will find stuff like #define new or #define GetMessage in such headers. Unlikely in your case, but something to always consider.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline TheLastArrived

  • Single posting newcomer
  • *
  • Posts: 9
Re: Using a DLL
« Reply #2 on: May 13, 2008, 12:08:25 pm »
Thank you for helping.

Let's try to be less vague.

I've to write an interface to a program, the program vendor gives a DLL and a header file to develop interface applications (too bad the vendor is no more accessible so no support available).

I create a std new wxWidget program, I include the header file then I use a function of the DLL  (TOpenDesign) in event handler and I get
Code
-------------- Build: Debug in DBXProva02 ---------------

Linking executable: bin\Debug\DBXProva02.exe
obj\Debug\DBXProva02Main.o: In function `ZN15DBXProva02Frame9OnNewFileER20wxFileDirPickerEvent':
D:/Sources/SCE/DBX Utilities/DBXProva02/DBXProva02Main.cpp:81: undefined reference to `_Z11TOpenDesignllPKcP10DbxContext@16'
collect2: ld returned 1 exit status
Process terminated with status 1 (0 minutes, 0 seconds)
1 errors, 0 warnings

Quite right, there is no reference to libraries, so I add the dll to "link libraries" list, retry building an get
Code
Linking executable: bin\Debug\DBXProva02.exe
D:\Programmi\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\mingw32\bin\ld.exe: cannot find -lDbx32.dll
collect2: ld returned 1 exit status
Process terminated with status 1 (0 minutes, 0 seconds)
1 errors, 0 warnings

It seems that the dll is built (and to be used) with MS VC++ (i'm using MinGW compiler) so I'm trying using pexports, dlltool and other tool to create an import library but I got no success yet.

There is something I'm missing?

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: Using a DLL
« Reply #3 on: May 13, 2008, 12:38:27 pm »
Quote
It seems that the dll is built (and to be used) with MS VC++ (i'm using MinGW compiler) so I'm trying using pexports
That works, but shouldn't even be necessary. I always link to MSVC DLLs directly, works every time.

Quote
Linking executable: bin\Debug\DBXProva02.exe
D:\Programmi\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\mingw32\bin\ld.exe: cannot find -lDbx32.dll
It can't find the library. Try giving it an absolute path (or project root relative), if nothing else helps.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline MortenMacFly

  • Administrator
  • Lives here!
  • *****
  • Posts: 9694
Re: Using a DLL
« Reply #4 on: May 13, 2008, 02:17:12 pm »
There is something I'm missing?
Enabling the full compiler log might help (see my sig).This may give you some more hints, e.g. a missing / wrong include path for the linker (not the compiler!).
Compiler logging: Settings->Compiler & Debugger->tab "Other"->Compiler logging="Full command line"
C::B Manual: https://www.codeblocks.org/docs/main_codeblocks_en.html
C::B FAQ: https://wiki.codeblocks.org/index.php?title=FAQ

Offline TheLastArrived

  • Single posting newcomer
  • *
  • Posts: 9
Re: Using a DLL
« Reply #5 on: May 13, 2008, 02:31:39 pm »
Quote
It seems that the dll is built (and to be used) with MS VC++ (i'm using MinGW compiler) so I'm trying using pexports
That works, but shouldn't even be necessary. I always link to MSVC DLLs directly, works every time.

well, it's quite an old DLLs maybe that's the problem

Quote
Linking executable: bin\Debug\DBXProva02.exe
D:\Programmi\MinGW\bin\..\lib\gcc\mingw32\3.4.5\..\..\..\..\mingw32\bin\ld.exe: cannot find -lDbx32.dll
It can't find the library. Try giving it an absolute path (or project root relative), if nothing else helps.

If I give an absolute path, C::B finds the lib but the undefined reference problem returns
Code
-------------- Build: Debug in DBXProva02 ---------------

Linking executable: bin\Debug\DBXProva02.exe
obj\Debug\DBXProva02Main.o: In function `ZN15DBXProva02Frame9OnNewFileER20wxFileDirPickerEvent':
D:/Sources/SCE/DBX Utilities/DBXProva02/DBXProva02Main.cpp:81: undefined reference to `_Z11TOpenDesignllPKcP10DbxContext@16'
collect2: ld returned 1 exit status
Process terminated with status 1 (0 minutes, 1 seconds)
1 errors, 0 warnings

Same problem if I link the import library (lib<name>.a) made with dlltool  or even if I link both the DLL and the .a :(
Missing function TOpenDesign is defined in header file as
Code
long __stdcall TOpenDesign(/* args list*/);
so I've tried dlltool with and without -U switch

Offline TheLastArrived

  • Single posting newcomer
  • *
  • Posts: 9
Re: Using a DLL
« Reply #6 on: May 13, 2008, 02:40:15 pm »
Enabling the full compiler log might help (see my sig).This may give you some more hints, e.g. a missing / wrong include path for the linker (not the compiler!).

Right, here you are
Dbx32.dll only linked:
Code
-------------- Build: Debug in DBXProva02 ---------------

mingw32-g++.exe -Wall -pipe -mthreads  -D__GNUWIN32__ -D__WXMSW__ -DWXUSINGDLL -DwxUSE_UNICODE  -g -D__WXDEBUG__    -ID:\Programmi\wxWidgets2.8\include -ID:\Programmi\wxWidgets2.8\contrib\include -ID:\Programmi\wxWidgets2.8\lib\gcc_dll\mswud  -c "D:\Sources\SCE\DBX Utilities\DBXProva02\DBXProva02Main.cpp" -o obj\Debug\DBXProva02Main.o
mingw32-g++.exe -Wall -pipe -mthreads  -D__GNUWIN32__ -D__WXMSW__ -DWXUSINGDLL -DwxUSE_UNICODE  -g -D__WXDEBUG__    -ID:\Programmi\wxWidgets2.8\include -ID:\Programmi\wxWidgets2.8\contrib\include -ID:\Programmi\wxWidgets2.8\lib\gcc_dll\mswud  -c "D:\Sources\SCE\DBX Utilities\DBXProva02\GUIFrame.cpp" -o obj\Debug\GUIFrame.o
windres.exe -i D:\Sources\SCE\DBXUTI~1\DBXPRO~1\resource.rc -J rc -o obj\Debug\resource.res -O coff -ID:\Programmi\wxWidgets2.8\include -ID:\Programmi\wxWidgets2.8\lib\gcc_dll\mswud
mingw32-g++.exe -Wall -pipe -mthreads  -D__GNUWIN32__ -D__WXMSW__ -DWXUSINGDLL -DwxUSE_UNICODE  -g -D__WXDEBUG__    -ID:\Programmi\wxWidgets2.8\include -ID:\Programmi\wxWidgets2.8\contrib\include -ID:\Programmi\wxWidgets2.8\lib\gcc_dll\mswud  -c "D:\Sources\SCE\DBX Utilities\DBXProva02\DBXProva02App.cpp" -o obj\Debug\DBXProva02App.o
mingw32-g++.exe -LD:\Programmi\wxWidgets2.8\lib\gcc_dll  -o bin\Debug\DBXProva02.exe obj\Debug\DBXProva02Main.o obj\Debug\GUIFrame.o obj\Debug\DBXProva02App.o  obj\Debug\resource.res   -lwxmsw28ud "D:\Sources\SCE\DBX Utilities\DBXProva02\Dbx32.dll"  -mwindows
obj\Debug\DBXProva02Main.o: In function `ZN15DBXProva02Frame9OnNewFileER20wxFileDirPickerEvent':
D:/Sources/SCE/DBX Utilities/DBXProva02/DBXProva02Main.cpp:81: undefined reference to `_Z11TOpenDesignllPKcP10DbxContext@16'
collect2: ld returned 1 exit status
Process terminated with status 1 (0 minutes, 24 seconds)
1 errors, 0 warnings

with libDbx32.a (-U switch) only linked:
Code
-------------- Build: Debug in DBXProva02 ---------------

mingw32-g++.exe -Wall -pipe -mthreads  -D__GNUWIN32__ -D__WXMSW__ -DWXUSINGDLL -DwxUSE_UNICODE  -g -D__WXDEBUG__    -ID:\Programmi\wxWidgets2.8\include -ID:\Programmi\wxWidgets2.8\contrib\include -ID:\Programmi\wxWidgets2.8\lib\gcc_dll\mswud  -c "D:\Sources\SCE\DBX Utilities\DBXProva02\DBXProva02Main.cpp" -o obj\Debug\DBXProva02Main.o
mingw32-g++.exe -Wall -pipe -mthreads  -D__GNUWIN32__ -D__WXMSW__ -DWXUSINGDLL -DwxUSE_UNICODE  -g -D__WXDEBUG__    -ID:\Programmi\wxWidgets2.8\include -ID:\Programmi\wxWidgets2.8\contrib\include -ID:\Programmi\wxWidgets2.8\lib\gcc_dll\mswud  -c "D:\Sources\SCE\DBX Utilities\DBXProva02\GUIFrame.cpp" -o obj\Debug\GUIFrame.o
windres.exe -i D:\Sources\SCE\DBXUTI~1\DBXPRO~1\resource.rc -J rc -o obj\Debug\resource.res -O coff -ID:\Programmi\wxWidgets2.8\include -ID:\Programmi\wxWidgets2.8\lib\gcc_dll\mswud
mingw32-g++.exe -Wall -pipe -mthreads  -D__GNUWIN32__ -D__WXMSW__ -DWXUSINGDLL -DwxUSE_UNICODE  -g -D__WXDEBUG__    -ID:\Programmi\wxWidgets2.8\include -ID:\Programmi\wxWidgets2.8\contrib\include -ID:\Programmi\wxWidgets2.8\lib\gcc_dll\mswud  -c "D:\Sources\SCE\DBX Utilities\DBXProva02\DBXProva02App.cpp" -o obj\Debug\DBXProva02App.o
mingw32-g++.exe -LD:\Programmi\wxWidgets2.8\lib\gcc_dll  -o bin\Debug\DBXProva02.exe obj\Debug\DBXProva02Main.o obj\Debug\GUIFrame.o obj\Debug\DBXProva02App.o  obj\Debug\resource.res   -lwxmsw28ud "D:\Sources\SCE\DBX Utilities\DBXProva02\libDbx32.a"  -mwindows
obj\Debug\DBXProva02Main.o: In function `ZN15DBXProva02Frame9OnNewFileER20wxFileDirPickerEvent':
D:/Sources/SCE/DBX Utilities/DBXProva02/DBXProva02Main.cpp:81: undefined reference to `_Z11TOpenDesignllPKcP10DbxContext@16'
collect2: ld returned 1 exit status
Process terminated with status 1 (0 minutes, 20 seconds)
1 errors, 0 warnings

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: Using a DLL
« Reply #7 on: May 13, 2008, 08:33:55 pm »
If I give an absolute path, C::B finds the lib but the undefined reference problem returns
Having it find the DLL at all is half of it already. Now, if it still misses a symbol, there are two possibilities left:
1. the symbol isn't in the DLL at all (wrong DLL)... duh :)
2. C++ name mangling. Either the DLL or your program (most likely your program) mangles names, and the respective other does not. Therefore the names aren't the same, and the linker doesn't find the symbol.
Solution: play with extern "C"
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline stahta01

  • Lives here!
  • ****
  • Posts: 7582
    • My Best Post
Re: Using a DLL
« Reply #8 on: May 14, 2008, 01:24:04 am »
Solution: play with extern "C"

But, he does not have the source. So, playing with extern "C" would be hard to use.

Edit: But, I just realized he most likely have a header that might need edited by added extern "C".

Tim S
« Last Edit: May 14, 2008, 01:35:17 am by stahta01 »
C Programmer working to learn more about C++ and Git.
On Windows 7 64 bit and Windows 10 64 bit.
--
When in doubt, read the CB WiKi FAQ. http://wiki.codeblocks.org

Offline stahta01

  • Lives here!
  • ****
  • Posts: 7582
    • My Best Post
Re: Using a DLL
« Reply #9 on: May 14, 2008, 01:33:22 am »
Do you have the header called Dbx32.h

What does the signature of the function TOpenDesign or whatever the function having linking problem look like.

I Goggled the below.

Code
long 
DLLX TOpenDesign (long language,
                  long version,
                  const char* pDesignName,
                  DbxContext* pContext);

If yes, the DLLX needs defined as something, but I am not sure what in your case.

Tim S
C Programmer working to learn more about C++ and Git.
On Windows 7 64 bit and Windows 10 64 bit.
--
When in doubt, read the CB WiKi FAQ. http://wiki.codeblocks.org

Offline thomas

  • Administrator
  • Lives here!
  • *****
  • Posts: 3979
Re: Using a DLL
« Reply #10 on: May 14, 2008, 08:55:15 am »
Edit: But, I just realized he most likely have a header that might need edited by added extern "C".
Well, yes :) Somewhere the function must be declared, after all.
"We should forget about small efficiencies, say about 97% of the time: Premature quotation is the root of public humiliation."

Offline TheLastArrived

  • Single posting newcomer
  • *
  • Posts: 9
Re: Using a DLL
« Reply #11 on: May 14, 2008, 09:54:47 am »
Update

@stahta01: DLLX is defined as __stdcall

extern "C": in Dbx32.h added
Code
#ifdef __cplusplus
extern "C"
{
#endif

.......

#ifdef __cplusplus
}
#endif


now if I try to build I get
Code
-------------- Build: Debug in DBXProva02 ---------------

Linking executable: bin\Debug\DBXProva02.exe
obj\Debug\DBXProva02Main.o: In function `ZN15DBXProva02Frame9OnNewFileER20wxFileDirPickerEvent':
D:/Sources/SCE/DBX Utilities/DBXProva02/DBXProva02Main.cpp:81: undefined reference to `TOpenDesign@16'
collect2: ld returned 1 exit status
Process terminated with status 1 (0 minutes, 0 seconds)
1 errors, 0 warnings

The prefixed underscores disappeared and the name more readable but the function is still missing.  :(
I tried with all possible combinations of .dll, .lib, lib<>.a w and w/o -U switch in dlltool. No way.
It's not likely I'm using wrong DLL, because it's part of a package with the header file, given with a CD by the vendor.

Offline TheLastArrived

  • Single posting newcomer
  • *
  • Posts: 9
Re: Using a DLL
« Reply #12 on: May 14, 2008, 11:02:46 am »
I've found this article, it seems it could be useful so I'll give it a read.
More news later :wink:

Offline TheLastArrived

  • Single posting newcomer
  • *
  • Posts: 9
Re: Using a DLL
« Reply #13 on: May 14, 2008, 11:15:04 am »
Bingo  :D

edit: I'm wrong don't do it... see some posts below
I've replace
Code
#define DLLX __stdcall
with
Code
#define DLLX __cdecl
in DBx32.h and now I get a beautiful
Code
Process terminated with status 0 (0 minutes, 26 seconds)
0 errors, 0 warnings

I hope it'll functions correctly :wink:
« Last Edit: May 19, 2008, 04:42:06 pm by TheLastArrived »