I am trying to create a DLL library, complete with a LIB interface, for use in other Symbian C++ programs. For this I seem to need a DEF file to be created from my code.
So I created a project, I have a pref file, I made my header and my cpp library, and it compiles. But how do I create the DEF file for the WINS platform? There seem to be no facilites inside CodeWarrior to create this def file, I need to use abld. But 'abld freeze' only creates the ARMS DEF file, and throws errors when creating the WINS DEF file. Am I missing something? How is the WINS DEF file created for a DLL when using VC++?
There is currently no way to freeze a def file from the IDE. It's pretty simple to create one manually though. If you have a .def file with EXPORTS in the first line, the linker will give you error messages stating what exports are missing. You can then copy from the errors window into the .def file and do a little editing. You can still build and test your dll and interface without having to recreate the .def file any time you change an interface. Just add EXPORTUNFROZEN to the .pref file.
Thanks for this thread of messages. I am now
closer to getting my DLL done. What I realized after reading your question and replies was that even though my .mpp file states the following :
DEFFILE myDefFile.def
// EXPORTUNFROZEN <-- this was commented out
The generated CodeWarrior project wasn't adding it to the document tree for building. I manually had to add the .def file myself. Now my DLL and LIB files are getting created for the WINS target, it's just that I'm getting Link errors stating that these exports are not yet frozen. Can't figure out why CodeWarrior insists on saying these exports aren't frozen yet when I can't even use the damn "abld freeze" command in my IDE.
My particular question is this :
How do I get CodeWarrior to freeze my exports now that I have them defined correctly in a .DEF
file? Do I have extra erroneous exports, e.g.,
NewLC, NewL, ~CMyClass (destructor)? Guess I
will have to write some test code for the DLL.
I grabbed an example .DEF file from the MSDN.
Look for "Export from a DLL using .DEF files".
(A Windows book also has examples, check out
"Win32 System Services 3rd ed by Marshall Brain,
pages 588-589 ISBN 0-13-022557-6)
For example, a DLL that contains the code to
implement a binary search tree might look like
the following:
LIBRARY BTREE
DESCRIPTION "Implements a binary tree."
EXPORTS
Insert @1
Delete @2
Member @3
Min @4
What the guy above said was to eliminate all of
the exports (Insert, Delete, Member, Min) lines
above and then try and build your DLL. The linker
will complain about missing exports and give
you the details on what should be in there,
i.e., stuff that looks like the above with the
ordinal numbers.
I went and put back in my API functions that I
thought should be exported plus the NewLC()
and NewL() and destructor methods.
Now, my .DLL and .LIB files get built ok,
it's just CodeWarrior that complains about
them not being frozen. This is where I'm stuck.
I also wanted to say that the documentation
didn't make it clear to me that E32DLL() was
needed in the source file implementation for
my DLL code. Check out the SDK v6.1 and look
for "How to implement a polymorphic interface
DLL". But the book I mentioned before by
Marshall Brain does mention the "entry-point
function" for a DLL (pages 598-599).
Also check out the book, "Programming for the
Series60 Platform and Symbian OS" by DIGIA
Chapter 5, pages 71-84 (ISBN 0-470-84948-7).
This clued me in to the IMPORT_C and EXPORT_C
macros for the header and implementation files.
Also told me how to worry about cleanup code
with the NewLC() and NewL() static functions.
Also talks about freezing the exports (which
we can't do with the IDE).
This other book, "Symbian OS C++ for Mobile
Phones" by Richard Harrison explains the
need for cleanup code better in section 6.2
(ISBN 0-470-85611-4)
Anyway, hope this thread helps me out more
as I hope it's helped you out.
If IMPORT_C and EXPORT_C and using correctly in your code, the linker will know what exports should be in the .def file. If you have a .def file in your project that has the correct exports, you will not get any errors or warnings. Since you are, your .def file does not match your code. The easiest way to get a matching .def file from the IDE is to remove everything from the .def file except the EXPORT keyword. Then when you make, the linker will tell you exactly what symbols are missing. You can copy from the errors window and paste into the .def file. You'll need to rearrange this text so it's in the proper format. That is:
This probably won't get you exactly what you want though since it sounds like you have other functions you want exported. This should let you know where you need to add in your IMPORT_C and EXPORT_C macros.
About the abld freeze functionality, Symbian has a perl script which will effectively "freeze" a .def file by deducing the exports from the IMPORT_C and EXPORT_C macros in your code. This has some dependencies on their command line build system and hence cannot be used from the IDE.
Thanks,
Wapa
Creating a Symbian DLL using Metrowerks CodeWarrior
2003-09-12, 18:59#6
Thanks wapawapa for your advice.
The only way I got CodeWarrior to stop
complaining with the link errors and warnings
about the exports not being frozen was this:
I not only took your advice and had the one
EXPORTS line all by itself (so that the linker
could specify exactly what is needed) but I cut
and pasted everything from those lines into
my DEF file.
By everything, I mean, everything...
including the mangled function name for each
exported entry plus the ordinal number PLUS
the actual reference name (which looks readable).
(These kind of exported entries are *not*
standard for non-Symbian DLL .DEF files.)
It wasn't until I cut and paste exactly what the
linker specified that the linker was happy.
Now I'm moving on to writing an app that will
test my DLL.
Thanks for your help.
--Ron
Creating a Symbian DLL using CodeWarrior IDE
2003-09-29, 21:28#7
Ok, so now I'm trying to get a example
project to use this DLL that I thought
I finally generated correctly.
The trouble is, the *&^#)@ linker complains
about "Undefined symbols" which refer to the
API calls that are part of my custom DLL.
I made sure the access paths were set up
correctly so that the DLL header file and the
import lib could be found correctly....nothing.
I even copied the "<myCustomDLL>.lib" and
"<myCustomDLL>.dll" files into the
"...\epoc32\release\WINSCW\UDEB\Z\SYSTEM\apps\
<ExampleAppDir>" even though they were both
already in the "...\epoc32\release\WINSCW\UDEB\"
directory so that the <ExampleApp> could find
them (.dll/.lib) easily....nothing.
I even tried using the STATICLIBRARY keyword
for my import lib in the .mmp file and
re-doing the whole project....nothing.
How in the heck will my example app make use
of the API in my custom DLL file (.lib/.dll)??
"LAA-LAA", if you're out there, please check
out this thread and help me out. You helped
out someone else's DLL problem (doctordwarf).
This is where I tried out your advice but
it's not working!
Any senior members out there that can help?
I would gladly appreciate it. Who knows?
Your posting might also benefit others trying
to get their custom DLLs to work also.
It sounds like you have everything setup correctly. The things to double check are:
- IMPORT_C is used in the header file before all exported functions
- EXPORT_C is used in the source file(s) before all exported functions
It may be a name mangling issue as well. You can right-click on your .lib and select disassemble. You'll be able to see the names of all symbols in the lib. Compare that to the symbols the linker says are missing.
in some cases the build problems are caused by insufficient platform list in bld.inf file. This happens often when you move from VC++ to CW or other way around. The emulator platform is in VC++ SDKs WINS, and in CW SDKs WINSCW. For example: you are moving from VC++ to Codewarrior, and bld.inf of your project looks like this:
PRJ_PLATFORMS
WINS THUMB ARMI
PRJ_MMPFILES
MyProject.mmp
MyProject2.mmp
In this case, you have to add the WINSCW to the platform row. While it's missing, you will encounter building and freezing problems.