Watch, Follow, &
Connect with Us

For forums, blogs and more please visit our
Developer Tools Community.


Welcome, Guest
Guest Settings
Help

Thread: Unresolved external...


This question is answered.


Permlink Replies: 2 - Last Post: Dec 22, 2017 1:17 PM Last Post By: Wei Sun Threads: [ Previous | Next ]
Wei Sun

Posts: 8
Registered: 8/14/17
Unresolved external...  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 21, 2017 5:13 PM
Hi, again,

While building a new VCL component, I got an error "Unresolved external 'Vcl::Graphics::TPicture::{1173}...' referenced from ....obj".

I use C++ Builder 10.2 Update 1, and turn off "Use 'classic' Borland compiler", and the linker is ilink32.

I've added rtl.bpi and vcl.bpi as Requires in my VCL Component project, what else should I add to the project for the missing TPicture?

---Edit:

A simplified version of codes that relate to TPicture
TPicture pic[5];
pic[0].LoadFromStream(...);//populate pic[0]. Image format is UNKNOWN.


I can't access implementation files of TPicture class, but I see default constructor is declared in header file. And after some reading, some says there is no such LoadFromStream from TPicture, but it is documented at http://docwiki.embarcadero.com/Libraries/Tokyo/en/Vcl.Graphics.TPicture.LoadFromStream

Edited by: Wei Sun on Dec 21, 2017 5:52 PM
Remy Lebeau (Te...


Posts: 9,447
Registered: 12/23/01
Re: Unresolved external... [Edit]
Correct
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 22, 2017 11:24 AM   in response to: Wei Sun in response to: Wei Sun
Wei Sun wrote:

TPicture pic[5];

You can't construct an array of TPicture objects on the stack like
that. TPicture derives from TObject, and TObject MUST be allocated
on the heap using the 'new' operator. So you need an array of
TPicture* pointers instead, eg:

TPicture* pic[5];
pic[0] = new TPicture;
...
delete pic[0];


Or, you use a smart pointer class like std::auto_ptr (pre-C++11) or
std::unique_ptr (C++11 and later) instead of using 'new'/'delete'
directly.

I can't access implementation files of TPicture class

Yes, you can. TPicture is implemented in Vcl.Graphics.pas in the
$(BDS)\Source\vcl folder. If you want to step into its source code at
runtime, you have to enable Debug DCUs in your project options.

And after some reading, some says there is no such LoadFromStream from
TPicture, but it is documented at
http://docwiki.embarcadero.com/Libraries/Tokyo/en/Vcl.Graphics.TPicture.LoadFromStream

The Berlin documentation shows TPicture::LoadFromStream() was still
'protected' and not directly accessible. The Tokyo documentation shows
it is 'public'. I don't have Berlin or Tokyo installed to verify, but
as of Seattle, it was indeed 'protected'.

However, TPicture does implement the IStreamPersist interface, which
has a LoadFromStream() method. So you can query TPicture for its
IStreamPersist interface (you can use Sysutils::Supports() for that) to
access LoadFromStream() in any version.

Not that it really matters, though, because TPicture::LoadFromStream()
simply calls TPicture::Bitmap::LoadFromStream() (at least up to
Seattle, anyway) , which is 'public', so you could use
pic[0]->Bitmap->LoadFromStream() instead of pic[0]->LoadFromStream().
But obviously, that cannot load non-BMP images.

The correct way to load a TStream into a TPicture in most versions is
to:

- detect the stream image type

- construct an object of the appropriate TGraphic-derived class for
that image type (TBitmap, TGifImage, TJpegImage, TPngImage, etc, or use
TWICImage)

- load the stream into that object

- Assign() the object to the TPicture

- destroy the object.

TPicture::LoadFromFile() does all of that, but
TPicture::LoadFromStream() does not (at least up to Seattle, anyway).

--
Remy Lebeau (TeamB)

Wei Sun

Posts: 8
Registered: 8/14/17
Re: Unresolved external... [Edit]  
Click to report abuse...   Click to reply to this thread Reply
  Posted: Dec 22, 2017 1:17 PM   in response to: Remy Lebeau (Te... in response to: Remy Lebeau (Te...
Thank you for the heads up about heap allocation and implementation file locations.

I’ll do the type-based initializations as you mentioned.
Legend
Helpful Answer (5 pts)
Correct Answer (10 pts)

Server Response from: ETNAJIVE02