-
Problems with implementing dlls
Hello,
I know this is a simple question, but I'm really stuck here; I even bought a book and made what was written there, but it didn't help.
I wan't to use the library wavelet2d from here. I'm using Visual Studio 2008. The documentation tells me that the files:
wavelet2d.lib
wavelet2d.h
wavelet2d.dll
libfftw3-3.dll
are needed. So I copied them to the source folder of my program. Then I right clicked on my project in the project-explorer and chose add-> existing element and chose to add wavelet2d.lib.
I tried to include a folder where I copied the files as an additional includepath, but that changed nothing.
What is going wrong? Do I have to #include something in my program? The functions of the lib aren't found.
I'm sorry if the names of the buttons in VS2008 I used are wrong, I'm german and I just translated the words.
Thanks in advance!
Best regards,
Nikolas
-
Re: Problems with implementing dlls
What type of errors do have? Compiler erros? Linker errors? Run-time errors?
-
Re: Problems with implementing dlls
error C3861: "dwt_sym": identifier not found.
Best regards,
Nikolas
-
Re: Problems with implementing dlls
Quote:
Originally Posted by
Physikant
error C3861: "dwt_sym": identifier not found.
What is "dwt_sym"? Where is it declared? If it is the wavelet2d.h then you had to
Code:
#include "wavelet2d.h"
in the file rhat uses this identifier.
-
Re: Problems with implementing dlls
It is in wavelet2d.h. If I include that file, I get a linker error:
error LNK2001: unresolved external symbol ""void * __clrcall dwt_sym(class std::vector<double,class std::allocator<double> > &,int,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::vector<double,class std::allocator<double> > &,class std::vector<double,class std::allocator<double> > &,class std::vector<int,class std::allocator<int> > &)" (?dwt_sym@@$$FYMPAXAAV?$vector@NV?$allocator@N@std@@@std@@HV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@00AAV?$vector@HV?$allocator@H@std@@@2@@Z)".
Thanks for the reply.
Best regards,
Nikolas
-
Re: Problems with implementing dlls
Good!
Now you have to add some libs containing these "unresolved external symbols". I presume there should be wavelet2d.lib library!
-
Re: Problems with implementing dlls
Try inserting
#pragma comment( lib, "wavelet2d")
at the top of the program. This will instruct the linker to load the wavelet2d.lib (looks first in the current working directory and then in the path specified in the LIB environment variable.)
-
Re: Problems with implementing dlls
I inserted the line at the beginnig of my code and I added wavelet2d.lib in the project-explorer as a ressource-file and in the main root of the project.
Still the external symbol can't be resolved.
Best regards,
Nikolas
-
Re: Problems with implementing dlls
Quote:
Originally Posted by
Physikant
I inserted the line at the beginnig of my code and I added wavelet2d.lib in the project-explorer as a ressource-file and in the main root of the project.
You should not do it. This .lib file has nothing to do with the resources.
You have to insert the file into project folder (note that I mean Windows Explorer folder, not a VS "project-explorer"!)
-
Re: Problems with implementing dlls
I removed the lib from the ressources folder again, but its still in the list of the project.
The lib-file is in the folder of my source on the hdd.
Any more ideas? :(
Best regards,
Nikolas Becker
-
Re: Problems with implementing dlls
Quote:
Originally Posted by
Physikant
I removed the lib from the ressources folder again, but its still in the list of the project.
The lib-file is in the folder of my source on the hdd.
Any more ideas? :(
Perhaps "the folder of your source on the hdd" is not "the current working directory"?
-
Re: Problems with implementing dlls
I've checked wavelet2d.lib and dwt_sym is defined there as an export. So there must be somethig wrong with how you are telling the linker to find/use wavelet2d.lib. Try putting the full path name to wavelet2d.lib in the #pragma statement - or add it to the linker additional dependencies property field for the project in MSVS.
-
Re: Problems with implementing dlls
Ok, I came back to this project and it's still not working.
I made a test project from scratch to make sure there is no problem with what ive done so far.
My project has this structure:
[1]wavelet2test
[2]wavelet2test\Debug
[3]wavelet2test\Release
[4]wavelet2test\wavelet2test
[5]wavelet2test\wavelet2test\Debug
[6]wavelet2test\wavelet2test\Release
What ive done:
In the download, there are two folders, Release and Debug. I copied the wavelet2d.dll and wavelet2d.lib from Debug to [2] and [5], and from the Release folder to [3] and [6]. Then I copied the libfftw3-3.dll from another directory of the download to [2],[5],[3] and [6].
Then I copied wavelet2d.h from the src-folder of the download to [1] and [4].
In the project-explorer, I added the wavelet2d.lib I copied to [2] as an element to the wavelet2test-project.
I added #include "wavelt2d.h" as the first line to my program.
I added [2],[3],[5],[6] to the directories for the linker.
In the program, I call dwt_sym (I think it has no namespace). If I do that, I get the two previously discussed linker errors LNK2028 and LNK2019.
If I add #pragma comment( lib, "wavelet2d") to the first lines of my code, I get many warnings in addition to the two linker errors (here is one of them, they are all similar):
warning C4272: "dwt_sym": is marked __declspec(dllimport); must specify native calling convention when importing a function.
Any ideas what i could try?
Thanks so far!
Best regards,
Nikolas
-
Re: Problems with implementing dlls
1. You did not mention "linker errors LNK2028 and LNK2019".
2. You neither added the wavelet2d.lib in the linker additional dependencies property field nor did you set the full path name to wavelet2d.lib in the #pragma statement. So you have just ignored what 2kaud suggested you in his latest post.
:sick:
-
Re: Problems with implementing dlls
Quote:
Originally Posted by
Physikant
It is in wavelet2d.h. If I include that file, I get a linker error:
error LNK2001: unresolved external symbol ""void * __clrcall dwt_sym(class std::vector<double,class std::allocator<double> > &,int,class std::basic_string<char,struct std::char_traits<char>,class std::allocator<char> >,class std::vector<double,class std::allocator<double> > &,class std::vector<double,class std::allocator<double> > &,class std::vector<int,class std::allocator<int> > &)" (?dwt_sym@@$$FYMPAXAAV?$vector@NV?$allocator@N@std@@@std@@HV?$basic_string@DU?$char_traits@D@std@@V?$allocator@D@2@@2@00AAV?$vector@HV?$allocator@H@std@@@2@@Z)".
Where to start...
First, I can't fathom why anyone would create a library that passes STL and/or C++ classes between DLL and application like this. You now have to verify that you're using the same compiler, compiler version (right down to the same service pack), compiler options, etc. to ensure that the link will work. This has been discussed on many threads here, with the bottom line being that a library shouldn't pass STL or any C++ objects across DLL/exe boundaries like this.
Unless you have complete documentation on the exact build options for your application (and you're using the same compiler), then you're going to get into more trouble trying to use this library.
I looked at the dll file using dependency walker. That function that is attempting to be resolved does not exist in that DLL. What exists in that DLL is exactly why my first point is relevant:
Code:
?dwt_sym@@YAPAXAAV...
See the difference? What you compiled and linked doesn't match the name that's in the DLL. The name is mangled differently in the DLL, meaning that the DLL was built differently. Add to that, the author may have used the _SECURE_SCL=0 macro (which optimizes the STL iterator logic in release versions). If they did and you didn't use that macro (or vice-versa), then at runtime, things will come crashing down.
This is the price that is paid when C++ objects and types are passed as parameters instead of standard types such as LONG, LPCTSTR, etc. You now have to basically have the entire set of the compile options you need to set before building your application.
Regards,
Paul McKenzie
-
Re: Problems with implementing dlls
Quote:
Originally Posted by
VictorN
1. You did not mention "linker errors LNK2028 and LNK2019".
2. You neither added the wavelet2d.lib in the linker additional dependencies property field nor did you set the full path name to wavelet2d.lib in the #pragma statement. So you have just ignored what 2kaud suggested you in his latest post.
:sick:
I think it's worse than that. Just the mere fact that the library is using C++ types as parameters ensures that something will go wrong somewhere.
Regards,
Paul McKenzie
-
Re: Problems with implementing dlls
@VictorN
I already added it to the additional dependencies for the linker, thats what i meant with the sentence "I added [2],[3],[5],[6] to the directories for the linker.". Sorry, I always have to translate this english terms to german, what makes it sometimes difficult to know if I found the right option.
I added the full path name, if I do it correctly, the two linker errors from my previous post appear again.
@Paul McKenzie
Thank you for the information. TBH, I don't really get whats the exact problem here. If I get this right, the author of the library made some terrible descisions which make it impossible for me to use this lib. So the best advice would be taking the source and trying to implement the whole library directly in my project (don't I violate some licenses by doing so?)?
Thanks!
Nikolas
-
Re: Problems with implementing dlls
Quote:
Originally Posted by
Physikant
Sorry, I always have to translate this english terms to german, what makes it sometimes difficult to know if I found the right option.
I agree.
My first expirience to work with the German version of VC++ 6.0 in 2000 let me move to the native (not for me but for VC++ 6.0 itself) English one. And after that I never ever tried to use some other than English VS language version (nor the Russian one despite Russian is my native language!)
-
Re: Problems with implementing dlls
Quote:
Originally Posted by
Physikant
@Paul McKenzie
Thank you for the information. TBH, I don't really get whats the exact problem here.
The problem as I see it is very simple.
When you create a C++ function, the C++ compiler needs to create a unique "stub" for this function so that the linker can resolve these functions. The issue with C++ is that functions can be overloaded, i.e. given the same name, but the parameters are different. So to make sure the linker sees two distinct functions, the C++ compiler intentionally mangles the name. The way the name is mangled is compiler dependent, but further compiler options can affect how a name is mangled.
Now the C++ compiler mangled the name, and now gives this name to the linker. The linker knows absolutely nothing about mangled names, non-mangled names, or even C++. All the linker knows is that it has a name, and is trying to match it with the names in the library you have. The name the linker is matching is not just "dwt_sym", as would suggest. It is that entire string you see there -- yes, including all of the @ characters, question marks, etc. To the linker, that is the function name, not "dwt_sym".
So that's why you get the error -- it is indeed the fact that the linker can't find that name in the DLL. Nothing more, nothing less.
Quote:
If I get this right, the author of the library made some terrible descisions which make it impossible for me to use this lib.
It is a good decision only if the author has laid out exactly how you are to set up your project to use the DLL, i.e. compiler options, preprocessor constants to set or unset, CRT to use, and most important, what compiler and version you must use. Contrast that to a DLL that has functions that do not use C++ types directly as parameters, and you then have much more flexibility. The issue though is that the library would have to be redesigned in a way so that these limitations are greatly reduced or even eliminated altogether.
Quote:
So the best advice would be taking the source and trying to implement the whole library directly in my project (don't I violate some licenses by doing so?)?
I don't think so if you are given the full source code. At this point, that may be the best thing to do, with the alternative being that you rebuild the DLL yourself using options that you are well aware of that can be copied to your EXE project.
Regards,
Paul McKenzie
-
Re: Problems with implementing dlls
So I put the parts of the library I need directly in my code. And there is the next problem: it uses libfftw3-3.dll.
On the homepage of libfftw3-3.dll (here, i found the dll, the header file and a .def file, together with the advice to use lib.exe /def:libfftw3-3.def to create a lib file. I did this and it brought me a .lib and a .exp-file. I copied them together with the .h and the .dll to to directory where the .h and the .cpp files of my program are. Then I added the .lib to my project. If I compile now, I get 3 errors for every call of a fuction from libfftw3-3.dll:
LNK2031(unable to generate p/invoke for "function_declaration" decorated_name; calling convention missing in metadata), LNK2028("exported_function" (decorated_name) referenced in function "function_containing_function_call" (decorated_name) ) and LNK2019(unresolved external symbol 'symbol' referenced in function 'function' ).
I think it wouldn't be that easy to copy the needed parts of libfftw3-3.dll from the source than it was from the parts of the wavelet2d.dll.
Sorry that this is so annoying :(
Nikolas
-
Re: Problems with implementing dlls
A while i thought that I solved it, but I just made the error to put the .dll to the additional dependencies instead of the .lib. If I put the .lib there instead, I get 2031, 2028 and 2019 again.
*sigh*
-
Re: Problems with implementing dlls
Quote:
Originally Posted by
Physikant
LNK2031(unable to generate p/invoke for "function_declaration" decorated_name; calling convention missing in metadata), LNK2028("exported_function" (decorated_name) referenced in function "function_containing_function_call" (decorated_name) ) and LNK2019(unresolved external symbol 'symbol' referenced in function 'function' ).
Looks like you're trying to use a native library in a managed (i.e. .NET) project. Probably C++/CLI, since all that confusion we see now would have been unlikely to arise in the first place if it were C# or even VB .NET.
Things like that can become really, really complicated, even when things like exporting C++ types from a native library (which isn't really recommended even in a purely native project) aren't involved at all.
This is rather advanced stuff that shouldn't really be done by people who don't know what they're doing - and not realizing at all that it's about a combination of managed and native stuff is a half-way certain indication of not really knowing what's going on.
I don't mean to say we're not going to help you because this is way over your head, but be prepared for a steep path to go...
-
Re: Problems with implementing dlls
The only functions calling libfftw are from the wavelet lib, which is in native c++, not managed. So it uses these data types, mainly vector. As I said, I copied the parts of the code form the wavelet lib to my main code and didn't change the data types.
What really bothers me is that the FFTW homepage suggests using it with VC++ and how this can be done, and it's still not working.
Anyway, I'm willing to learn and spend some time with it, so if someone would help me here, I really would be happy :)
Nikolas
-
Re: Problems with implementing dlls
In that case I'd suspect that you unintentionally activated CLR support for at least one of your source files. So I'd suggest you carefully check your project settings for that; not just the general settings, but also those for the individual .cpp files. I can't imagine how the LNK2031 error could arise without at least one managed module being involved.
-
Re: Problems with implementing dlls
Oh, one of my source files uses managed code! Basically, i've got a gui with the .net librarys. I call from this code a function of the wavelet library. This function (and all that are needed for the function) is in a seperate file, and this one only uses c++ native (and my managed code only calls the function with c++ native variables). This function now calls libfftw. So thats why i've got problems? That a part of my program uses managed code, although the function using the lib only uses native stuff?
And if yes, is there any workaround except trying to implement the needed libfftw-parts directly in my program from the source (which sounds really ugly) ?
-
Re: Problems with implementing dlls
Ok, then first change the CLR support option of all your managed modules to /clr if it currently is /clr:pure, which is the default for an IDE-created Windows Forms project (at least in the 2010 version). IMO the pure part of the option is rather counter-productive in a mixed-code project anyway and removing it may instantly fix your LNK2031 issue, since that changes the default calling convention assumed for free functions in the managed modules from __clrcall to __cdecl.
If that doesn't help you may try explicitly specifying the calling convention __cdecl in the offending function's declaration, as described in the linker error's MSDN documentation. However, that probably would require changing the 3rd-party librarie's .h file(s), so you may want to avoid it.
The above suggestions are meant to fix the LNK2031 error, yet there still may be other problems you'll need to solve. Unless you're exclusively calling extern "C" __cdecl functions (with appropriate parameter types) across DLL boundaries, that may well be the issues already discussed in this thread. Or it may be completely new issues that have been obscured by others so far. At any rate, getting rid of the LNK2031 will take you a significant step forward.
-
Re: Problems with implementing dlls
Quote:
Originally Posted by
Physikant
I'm willing to learn and spend some time with it, so if someone would help me here, I really would be happy :)
Nikolas
What you should do is to start from scratch.
Create a brand new, non-managed C++ project, and then attempt to use the library using a very small main() program by calling a couple of the functions. The functions need not even make sense in the manner or paramters used -- the goal is to create a program that compiles and links successfully. Nothing more than that.
Then when you run it, all you need is to see if the main() program starts without error (no DLL not found issues). And that's it. Then you move onwards with the larger project, with the knowledge of knowing how to set things up correctly.
That is the way you learn how to properly use DLL's, and also diagnose any problems. Also doing things this way aids in you learning why things work or don't work with respect to lib files, DLL's, etc..
Otherwise, you'll be fighting with this much larger project with very little to no hope of actually getting things done. Once you have the smaller project working, then and only then would you apply the same steps to the larger project.
Regards,
Paul McKenzie
-
Re: Problems with implementing dlls
Hello,
i've did it :)
The suggestion of Eri523 solved the problem.
Thanks to everyone who spent his time to help me.
Best regards,
Nikolas