delphi - How do I solve an unresolved external when using C++ Builder packages? -
i'm experimenting reconfiguring application make heaving use of packages. both , developer running similar experiment running bit of trouble when linking using several different packages. we're both doing wrong, goodness knows :)
the situation this:
- the first package,
packagea.bpl
, contains c++ classfooa
. class declaredpackage
directive. the second package,
packageb.bpl
, contains class inheritingfooa
, calledfoob
. includesfoob.h
, , package built using runtime packages, , linkspackagea
adding referencepackagea.bpi
.when building
packageb
, compiles fine linking fails number of unresolved externals, first few of are:[ilink32 error] error: unresolved external '__tpdsc__ fooa' referenced c:\blah\foob.obj
[ilink32 error] error: unresolved external 'fooa::' referenced c:\blah\foob.obj
[ilink32 error] error: unresolved external '__fastcall fooa::~fooa()' referenced blah\foob.obj
etc.
running tdump on packagea.bpl
shows:
exports packagea.bpl 14 exported name(s), 14 export addresse(s). ordinal base 1. sorted name: rva ord. hint name -------- ---- ---- ---- 00002a0c 8 0000 __tpdsc__ fooa 00002ad8 10 0001 __linkproc__ fooa::finalize 00002ac8 9 0002 __linkproc__ fooa::initialize 00002e4c 12 0003 __linkproc__ packagea::finalize 00002e3c 11 0004 __linkproc__ packagea::initialize 00006510 14 0007 fooa:: 00002860 5 0008 fooa::fooa(fooa&) 000027e4 4 0009 fooa::fooa() 00002770 3 000a __fastcall fooa::~fooa() 000028dc 6 000b __fastcall fooa::method1() const 000028f4 7 000c __fastcall fooa::method2() const 00001375 2 000d finalize 00001368 1 000e initialize 0000610c 13 000f ___cppdebughook
so class seems exported , available link. can see entries specific things ilink32 says it's looking , not finding. running tdump on bpi file shows similar entries.
other info
the class descend tobject, though before refactoring packages normal c++ class. (more detail below. seems "safer" using vcl-style classes when trying solve problems delphi-ish thing anyway. changing changes order of unresolved externals first not find method1
, method2
, others.)
declaration fooa
:
class package fooa: public tobject { public: fooa(); virtual __fastcall ~fooa(); fooa(const fooa&); virtual __fastcall long method1() const; virtual __fastcall long method2() const; };
and foob
:
class foob: public fooa { public: foob(); virtual __fastcall ~foob(); ... other methods... };
all methods implemented in .cpp files, it's not not finding them because don't exist! .cpp files contain #pragma package(smart_init)
near top, under includes.
questions might help...
- are packages reliable using c++, or useable delphi code?
- is linking first package adding reference bpi correct - how you're supposed it? use lib seems make second package larger, , suspect it's statically linking in contents of first.
- can use
package
directive ontobject
-derived classes? there no compiler warning using on standard c++ classes. - is splitting code packages best way achieve goal of isolating code , communicating through defined layers / interfaces? i've been investigating path because seems c++builder / delphi way, , if worked looks attractive. there better alternatives?
- i'm new using packages , have known them through using components before. general words of advice great!
we're using c++builder 2010. i've fabricated class , method names in above code examples, other details we're seeing.
unresolved external
the unresolved external in case, seems because compiler unable find path package data. should find out if:
- the path exists in compiler search path list.
- the package exists in default package directory.
if 1 of them true path isn't problem. riho mentions cause problem. embarcadero documentation wiki states following unresolved external error:
the named symbol referenced in given module not defined anywhere in set of object files , libraries included in link. check make sure symbol spelled correctly.
you see error linker c or c++ symbols if of following occur:
- you did not match symbol’s declarations of
__pascal
,__cdecl
types in different source files.- you have omitted name of object file program needs. need manually add required packages requires list.
- you did not link in emulation library.
if linking c++ code c modules, might have forgotten wrap c external declarations in extern “c”.
you have case mismatch between 2 symbols.
source: unresolved external 'symbol' referenced 'module'.
since seems - although altered class names - not case of misspelling. state have added package requires list rule out well. since not linking c modules can omit part well. points problems directory.
about other questions
your questions interesting , many of questions questions self has been looking answers when started developing packages , components c++ builder.
are packages reliable using c++?
packages fine solution use c++ builder, both c++ builder built support packages , pascal written vcl framework. means implementations different in c++ builder other compilers. necessity keep language compatible delphi sibling. reason can use packages in c++ builder almost if using delphi.
is linking first package adding reference bpi correct?
to start second part of question here, using lib file makes package larger because using static linking - guess correct. first part of question, linking package fine adding reference bpi. need make sure path variable has been set correctly riho suggests in answer.
personally make sure packages proper directories in users folder, location of depending on delphi version , operating system version. far recall under document , settings\all users\shared documents\rad studio(version number)\packages mistaken that.
can use package
directive on tobject
-derived classes?
the package
macro resolved __declspec(package)
, can compare __declspec(dllexport)
. difference between these package used when declared in package, , dllexport used when declared in dll. there topic on official embarcadero forums titled __declspec(package) vs __declspec(dllexport). author of original post, asks exact question this, unfortunately part of question unanswered.
i have theory however, , must emphasize nothing more theory. remy lebeau writes response question in forum post:
__declspec(dllexport) can used plain functions, data variables, , non-vcl classes, , can used in plain dlls. __declspec(package) used vcl components, , can used packages.
so reading response seems me package exporting class, dllexport does. , since dllexport far can read response used in plain dlls have use package exporting (even) non vcl classes package.
what interesting this, package dll far recall, must admit can't find or remember source of information take grain of salt.
is splitting code packages best way achieve goal of isolating code?
packages have prominent strengths when creating reusable components vcl. using packages limits user use either c++builder or delphi, components written take advantage of vcl framework it's excellent choice. written packages can ease reusability of components, , believe preferred method of distributing components vcl.
however if code not take advantage of vcl framework in way, consider using ordinary library, either static or dynamic, create more cross compiler friendly approach.
whether there better approach isolating code, depends on project working on. keep code communicates through use of vcl classes in packages, code not require use of vcl classes in regular libraries. keep in mind though can use vcl classes in dll need handle special cases if choose export functions vcl string classes parameters or return values.
any general words of advice?
i'm not experienced developer of packages myself, have found disabling runtime linking solves lot of problems, while trivial fix problems own code, can run 3rd party components have trouble dealing this. having said that, i'm not fan of distributing packages along application required in case. honest matter of taste.
personally found difficult find proper answers many of questions, when started creating components , packages. official helpfile not informative on matter, looking through vcl source code, give best answer question. besides there few other websites can provide help, many of sites targeting delphi though, have used though.
delphi wikia has articles creating components, in particular creating components , creating packages there bcb journal 1 of few c++ builder specific sites, has fine articles , acceptable forum. delphi pages @ about.com source of information, i've found lots of hints , nice knows there, in particular: creating custom delphi components - inside , out.
Comments
Post a Comment