wxString already defined in dll Topic is solved

If you are using the main C++ distribution of wxWidgets, Feel free to ask any question related to wxWidgets development here. This means questions regarding to C++ and wxWidgets, not compile problems.
briceandre
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 672
Joined: Tue Aug 31, 2010 6:22 am
Location: Belgium

Post by briceandre »

Why did you remove part of them ?

My feeling is that you need at least WXUSINGDLL, but maybe you can try with all of them ?

Note that you should provide those options for your own dll compiled files, but also for your main app compiled files.

Some of those flags are used for the naming convention of exported symbols of the dll. So, both the caller and the callee shall define the same symbols so the functions decorations are the same on each side.
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 539
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Post by mael15 »

i thought, i.e. WXMAKINGDLL_CORE would not make sense in my dll?
when i use all of these options, the errors change to other elements.

could you perhaps try to change a wxwidgets sample from using static linking to dynamic? then i could see what steps are nescessary?

i tried finding tutorials about how to link to wxWidgets dynamically, but to my surprise could not find any.
briceandre
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 672
Joined: Tue Aug 31, 2010 6:22 am
Location: Belgium

Post by briceandre »

i thought, i.e. WXMAKINGDLL_CORE would not make sense in my dll?
I don't think this one is necessary. Maybe you can try removing it, maybe it will help. But I am pretty sure the 'WXUSINGDLL' is mandatory in your case.

Post new outputs of the compiler so we can help. (join compiler or linker command lines with outputs)
could you perhaps try to change a wxwidgets sample from using static linking to dynamic? then i could see what steps are nescessary?
Personnaly, I cannot because I am not using VC++ development environment. But are you sure samples provided with wxWidgets don't provide VC++ projects that can compile with shared library ? They provide Makefiles for other compilers that allow static and dynamic linking. So, I would be surprised if it was not possible with VC++...
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 539
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Post by mael15 »

ok, here it comes for configLib.dll:

first five lines:
1>dlgconfig.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""protected: static struct wxEventTable const wxDialogBase::sm_eventTable" (?sm_eventTable@wxDialogBase@@1UwxEventTable@@B)".
1>plotterconfigevent.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""protected: static class wxStockGDI * wxStockGDI::ms_instance" (?ms_instance@wxStockGDI@@1PAV1@A)".
1>subcalibration.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""protected: static class wxStockGDI * wxStockGDI::ms_instance" (?ms_instance@wxStockGDI@@1PAV1@A)".
1>testingdeviceconfig.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""protected: static class wxStockGDI * wxStockGDI::ms_instance" (?ms_instance@wxStockGDI@@1PAV1@A)".
1>xmlbase.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""protected: static class wxStockGDI * wxStockGDI::ms_instance" (?ms_instance@wxStockGDI@@1PAV1@A)".
i hope you do not mind the german, it says "unresolved external symbol".

compiler:
/I"F:\wxWidgets_2_9\include" /I"F:\wxWidgets_2_9\include\msvc" /I"E:\_WINOHNEDLL\src" /I"E:\libxml2-2.7.3.win32\include" /I"E:\libecwda\src" /I"F:\Programme\National Instruments\NI-DAQ\DAQmx ANSI C Dev\include" /ZI /nologo /W3 /WX- /Od /Oy- /D "WIN32" /D "WINVER=0x0400" /D "_USRDLL" /D "DLL_EXPORTS" /D "_DEBUG" /D "__WXDEBUG__" /D "__WXMSW__" /D "_WINDOWS" /D "WXUSINGDLL" /D "WXMAKINGDLL_CORE" /D "wxUSE_BASE=0" /D "wxUSE_GUI=1" /D "_WINDLL" /D "_UNICODE" /D "UNICODE" /Gm /EHsc /RTC1 /GS /fp:precise /Zc:wchar_t /Zc:forScope /GR /Fp"Debug\libConfig.pch" /Fa"Debug\" /Fo"Debug\" /Fd"Debug\vc100.pdb" /Gd /FI"F:\wxWidgets_2_9/include/wx/wxprec.h" /FI"F:\wxWidgets_2_9/include/msvc/wx/setup.h" /analyze- /errorReport:queue
linker:
/OUT:"E:\libconfig\lib\libConfig.dll" /INCREMENTAL /NOLOGO /LIBPATH:"F:\wxWidgets_2_9\lib\vc_dll" /LIBPATH:"E:\libxml2-2.7.3.win32\lib" /LIBPATH:"E:\libecwda\lib" /DLL "wxmsw29ud_core.lib" "wxbase29ud.lib" "comctl32.lib" "rpcrt4.lib" "winmm.lib" "advapi32.lib" "wsock32.lib" "ecwdaWin.lib" "libxml2.lib" "kernel32.lib" "user32.lib" "gdi32.lib" "winspool.lib" "comdlg32.lib" "shell32.lib" "ole32.lib" "oleaut32.lib" "uuid.lib" "odbc32.lib" "odbccp32.lib" /MANIFEST /ManifestFile:"Debug\libConfig.dll.intermediate.manifest" /ALLOWISOLATION /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"E:\libconfig\lib\libConfig.pdb" /SUBSYSTEM:WINDOWS /PGD:"E:\libconfig\lib\libConfig.pgd" /TLBID:1 /DYNAMICBASE /NXCOMPAT /MACHINE:X86 /ERRORREPORT:QUEUE
briceandre
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 672
Joined: Tue Aug 31, 2010 6:22 am
Location: Belgium

Post by briceandre »

Libraries seem to be correctly included in link operation so, I am pretty sure this is a name decoration problem. This problem generally occurs with invalid defines in the project.

If you want to check the name decorations, just to be sure, there are specific tools that can help you. With the gcc suite (mingw under windows), you can examine the symbols of your objects by using 'objdump -t <obj_file>'. If names present in the obj file do not match the ones in your 'unresolved external symbol' warnings, this means that this is your problem. The tool 'objdump' will most probably work on the objects generated with VC++, so you can try if you want. If you perform this operation, you can post the output, i will help you determining if the problem is caused by name decorations.

I am sorry but I cannot help you furthermore as I am not a specialist of VC++.

Maybe you can move this thread in the 'Compiler / Linking / IDE Related' section of the forum. You will maybe find other persons more able to help you.

Just one last question : I am surprised of the name of the 'unresolved external symbol' in your log. In general (or, at least, with mingw), when calling functions defined in a dll, they are prefixed with something like '__imp__'. Are you sure you rebuilt everything after changing the compilation oprtions ?
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 539
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Post by mael15 »

hi andre,

i tried objdump and it gives me a 5mb txt file. i do not understand the contents of that file, but here are two examples:

compiler error:
testingdevicepropertylist.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""bool const wxFalse" (?wxFalse@@3_NB)".
objdump of testingdevicepropertylist.obj contains:
AUX scnlen 0x178 nreloc 7 nlnno 0 checksum 0x0 assoc 830 comdat 5
AUX scnlen 0xb2db23ad nreloc 0 nlnno 0
[3092](sec 830)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x00000000 ??0?$wxArgNormalizerWchar@ABVwxString@@@@QAE@ABVwxString@@PBVwxFormatString@@I@Z
[3093](sec 0)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 ?wxFalse@@3_NB
[3094](sec 0)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x00000000 ?wxOnAssert@@YAXPBDH000@Z
[3095](sec 832)(fl 0x00)(ty 0)(scl 3) (nx 2) 0x00000000 .rdata
AUX scnlen 0x28 nreloc 0 nlnno 0 checksum 0x1e399566 assoc 0 comdat 2

other compiler error:
testingdevicepropertylist.obj : error LNK2001: Nicht aufgelöstes externes Symbol ""void (__cdecl* wxTheAssertHandler)(class wxString const &,int,class wxString const &,class wxString const &,class wxString const &)" (?wxTheAssertHandler@@3P6AXABVwxString@@H000@ZA)".
objdump file contains:
AUX scnlen 0x0 nreloc 0 nlnno 0
[3110](sec 835)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 ??_C@_0CN@DMIBKMPN@format?5specifier?5doesn?8t?5match?5a@
[3111](sec 0)(fl 0x00)(ty 0)(scl 2) (nx 0) 0x00000000 ?wxTheAssertHandler@@3P6AXABVwxString@@H000@ZA
[3112](sec 0)(fl 0x00)(ty 20)(scl 2) (nx 0) 0x00000000 ?GetArgumentType@wxFormatString@@QBE?AW4ArgumentType@1@I@Z
[3113](sec 836)(fl 0x00)(ty 0)(scl 3) (nx 2) 0x00000000 .text
AUX scnlen 0x9d nreloc 9 nlnno 0 checksum 0x9219dbf3 assoc 0 comdat 2
so that means name decoration is not my problem?
Are you sure you rebuilt everything after changing the compilation options ?
i never changed the options of the wx build and i could not build my dll which has no other dependancies than wx. what would you mean by "everything"?

thanx a lot for taking the time to help me! i will post this problem in the ide related section of the forum.
briceandre
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 672
Joined: Tue Aug 31, 2010 6:22 am
Location: Belgium

Post by briceandre »

In fact, what would be interesting is to perform the objdump on the linked library (in your case, the wxWidgets libraries). When the compiler tells you that it does not find corresponding symbol, it means that it finds the call in your obj, but not the callee in the provided libs. The name will thus always match the one in the obj, but maybe not the one exported in the libs.
i never changed the options of the wx build and i could not build my dll which has no other dependancies than wx. what would you mean by "everything"?
What I mean is that, when you compile your lib, each .c file is compiled separately and, when they are all compiled, the link is performed. But, when you recompile your lib, IDE's generally only recompile the .c files that were modified (or if they include .h files that were modified).

Depending on your IDE, it will maybe recompile everything if project options were changed, but I am not sure of that. It depends on the IDE, and I don't know the behaviour of VC++.

As name decoration is performed during compilation, if your objects are not recompiled, it is useless to change compilation options. It will not have any effect.

To be sure you recompile everything, you can force a clean by suppressing all .o files (generally, IDE have specific interface to perform that such as 'clean' command or 'rebuild all' or something like that).
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 539
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Post by mael15 »

To be sure you recompile everything, you can force a clean by suppressing all .o files
oh, i see. yes, i used the clean command and it did not change the problem.

how can i find out in which wx lib the symbol wxFalse should be? [/quote]
briceandre
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 672
Joined: Tue Aug 31, 2010 6:22 am
Location: Belgium

Post by briceandre »

ow can i find out in which wx lib the symbol wxFalse should be
I don't know, I guess it is in the 'wxbase29ud.lib', but you can try both of them. Do not forget the '-t' option. If you have cygwin or MSys, you can use 'grep' to find the interesting lines :

objdump -t wxbase29ud.lib | grep wx...
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 539
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Post by mael15 »

i checked all 22 libs and "wxFalse" is in none of them. does this mean that something went wrong with the wxWidgets compilation?
briceandre
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 672
Joined: Tue Aug 31, 2010 6:22 am
Location: Belgium

Post by briceandre »

i checked all 22 libs and "wxFalse" is in none of them. does this mean that something went wrong with the wxWidgets compilation?
Not sure, I would try with a function call. I am not sure -t option lists objects declarations.
Last edited by briceandre on Thu Oct 28, 2010 3:54 pm, edited 1 time in total.
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 539
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Post by mael15 »

i can compile the dll just fine when i use the lib dir vc_lib instead of vc_dll. but that does not help me, because i MUST link dynamically. otherwise i get a lot of "symbol wxXYZ already defined in XYZ.lib" errors when compiling my app. :?:
briceandre
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 672
Joined: Tue Aug 31, 2010 6:22 am
Location: Belgium

Post by briceandre »

i can compile the dll just fine when i use the lib dir vc_lib instead of vc_dll
Name decoration is not the same when calling a function declared in a dll compared to one declared in a static link. Thus, if it compiles fine with the static link, and if you do not change compilation options when trying to link with dynamic link, it just convince me that this the origin of your problem.
otherwise i get a lot of "symbol wxXYZ already defined in XYZ.lib" errors when compiling my app.
As explained before, if you perform static link with your dll and with your app, you include twice the wxWidgets stuff. Thus, if you want your lib to be a dll (which is maybe not necessary ? depends on what you need...), you must link it dynamically
mael15
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 539
Joined: Fri May 22, 2009 8:52 am
Location: Bremen, Germany

Post by mael15 »

it just convince me that this the origin of your problem
so how can i get the missing symbols to show up in the libs included in the vc_dll dir?!
briceandre
Ultimate wxWidgets Guru
Ultimate wxWidgets Guru
Posts: 672
Joined: Tue Aug 31, 2010 6:22 am
Location: Belgium

Post by briceandre »

OK, I will try to explain the theory, but you will have to search a little bit by yourself to apply it to your problem (or to find someone that has exactly the same configuration).

Imagine that you define a lib with an exported function :

Code: Select all

void toto (void);
You have two possibilities : either you compile a static lib. In this case, no problem. Or you compile a dynamic library. In this case, the program that will use your function WILL NOT DIRECTLY call it !!!

In order for the program to use your function (compiled in a dynamic lib), it has two options :
- The first one, it manually loads the lib (with an os-specific system call), it finds in the loaded dll the entry address of the toto function with a second os-specific system call and it performs the call with the resulting pointer (note that it is advised to store this pointer so that you do not search it anymore for second call)
- The second option is simplier : if you generate your dll with your compiler, you can ask him to generate what is called an 'inclusion library' (same name as the dll, but with a .lib extension for VC++). This library is a static library that performs all the stuff explained above for you. But, in this case, you do not call 'toto' : you call the corresponding entry in the inclusion library. You perform a static link with this inclusion library, and it will dynamically load your dll at runtime for you.

Now, if you choose the second option (which is, I think , the better choice), you should explain to the compiler that you are going to use an inclusion library. This is a compiler-dependant stuff to explain that to the compiler and this is, I think, the problem you are encountering...

For example (and I think this is the convention used by VC++), one possibility is to declare the 'toto' funcgtion like this :

Code: Select all

__declspec(dllexport) void toto(void);
So, when wxWidgets coders have implemented your favourite toolkit, they did not known if you wanted to use static or dynamic link. They also did not know which compiler you wanted to use. So, they wrote code like that (simplified version...):

Code: Select all

#ifdef VCPP
#ifdef SHARED
#define DLL_EXPORT __declspec(dllexport)
#else 
#define DLL_EXPORT
#endif
#else
...
#endif

DLL_EXPORT void toto(void);
With this code, to perform a static link with VC++, you can compile this by defining VCPP. If you want to perorm a dynamic link with VC++, the code does not change, but you compile this with VCPP and SHARED.

Now, my example is a stupid one, but wxWidgets uses same mechanisms (with different macro names). If you are using Linux, there is a tool that can help you defining which flags you should add during compilation. If you are using Windows, I don't think that such a mechanism exists and so, you must define your compilation flags by hand.

If you have no idea of which flags you should put, there are three alternatives:
- Either you try different combinations until you find proper one (will maybe request a lot of time)
- Either you check in the code to guess which flags should be set to generate the proper code
- Or you find someone that exacly knows which flags to set for your problem.

I know the mechanisms, but I don't known the exact flags that you sould set because I am not using the same environment as you.

Hope this helps you understanding your problem, and maybe will help you find the solution.

Note that the advantage of checking with objdump is that you can check if naming decoration matches. You maybe will tell me that if it matches, you will not need objdump to confirm you that. But, if you have more than one problem in your compilation process, it will maybe allow you to save time...
Post Reply