Sign in Join

Live chat for Free Pascal, Lazarus, Delphi and every Pascal programmer.

Mailing lists / lazarus / 2001-04

FPC - Help Needed -Dynamic Linking

5 messages · 2 people ·

Reply by email Subscribe to this list Your subscription

Read-only archive. Use j and k to move between messages.

Shane Miller

UPDATE:
Even if ComponentPages existed in the main executable (I registered some components and therefore created a tcomponentpages) when the linked library calls the registercomponents function, it thinks that COmponentPages is not assigned. I guess that is reasonable but how can I get it to use the ComponentPages instance from the main executable???

Shane
"I'm getting a headache"

>> 04/06/01 01:06PM >>>

Greetings,

In order to create Packages for Lazarus I am dynamically linking a unit into Lazarus. I am using the dl functions DLOpen, DLClose, DLSym to facilitate this.

I open the library, then call dlsym to get the pointer to the procedure I want to call. That works fine. Then I call the procedure. Inside the library unit's exported function I call a function (register) in another unit that's in the uses clause. In the Register function of that unit I call RegisterComponents. This calls the function within creginst.inc unit. Because this is the first registration and the ComponentPages is not assigned it calls InitComponentPages. Somewhere within the TCollection.Create the funciton throws an exception.

Can someone look into that code and tell me if it's related to the dynamic linking or if it's simply an error in the InitComponentPages code?

I really have been struggling trying to trace this down and would appreciate any help.

Thanks
Shane

_________________________________________________________________ To unsubscribe: mail with
"unsubscribe" as the Subject
archives at http://www.miraclec.com/list_archives/lazarus

Reply by email

Unknown author
to Shane Miller: OK, how about this. What is I change the RegisterComponents procedure in creginst.inc to:
Shane Miller wrote 25 lines
OK, how about this. What is I change the RegisterComponents procedure in creginst.inc to: If RegisterComponentsProc nil then RegisterComponentsProc(Page,ComponentClasses); Then in the library I will have this code: Function DoRegistering : TSomerecordstructure; procedure registercomponentcallback(const Page : String; ComponentClasses : TComponentClasses); begin //Add the PAGE and TComponentClass info to the RESULT of the parent function end; Begin RegisterComponentProc := @RegisterComponentCallback; //call the register methods in each unit; end; this way the Lazarus.exe would load the library, call the DoRegistering function and take the return value and do the registering.

It would be easier to set a callback and call this for each component to be registered.

SetRegisterCallback(LazarusCallBack);
RegisterComponents;

The 'LazarusCallBack' is a function in lazarus which registers 1 component. The registercomponents function in the library registers all components it knows about with the callback.

Show quoted text 5 lines
The only problem I see with that is that the Lazarus program knows nothing about the ComponentClasses that are returned to it. If, for example, I registered a TButtonPlus class, Lazarus would know nothing about it because all the information about it is in the library.

Exactly, and this cannot be solved unless we implement package support.

Would this work?

It will work, but you cannot do any 'XXX is YYY' stuff on these registered components. You could do some extra registering of TComponent VMT's:

Type
  TLibraryComponent = Class of TComponent;
Var
  LibTComponent : TLibraryComponent
  LibTComponent:=GetLibRaryComponentVMT;

Then you could do

  If Instance is LibTComponent then
    ...

But this will require keeping a record for each library with at least the VMT's of TComponent and TPersistent.

Michael.

Reply by email

Shane Miller
to Unknown author: (and more specifically the heap manager) are not initialized. What I suggest you to do…

OK, how about this. What is I change the RegisterComponents procedure in creginst.inc to:

If RegisterComponentsProc  nil then
  RegisterComponentsProc(Page,ComponentClasses);

Then in the library I will have this code:

Function DoRegistering : TSomerecordstructure;
     procedure registercomponentcallback(const Page : String;
ComponentClasses : TComponentClasses);
         begin
             //Add the PAGE and TComponentClass info to the RESULT of the
parent function
         end;
Begin
   RegisterComponentProc := @RegisterComponentCallback;
  //call the register methods in each unit;
end;

this way the Lazarus.exe would load the library, call the DoRegistering function and take the return value and do the registering.

The only problem I see with that is that the Lazarus program knows nothing about the ComponentClasses that are returned to it. If, for example, I registered a TButtonPlus class, Lazarus would know nothing about it because all the information about it is in the library.

Would this work?

Thanks again
Shane

Earlier message 71 lines
----- Original Message ----- From: To: Sent: Friday, April 06, 2001 5:39 PM Subject: Re: [lazarus] FPC - Help Needed -Dynamic Linking > > > On Fri, 6 Apr 2001, Shane Miller wrote: > > > Greetings, > > > > In order to create Packages for Lazarus I am dynamically linking a unit > > into Lazarus. I am using the dl functions DLOpen, DLClose, DLSym to > > facilitate this. > > > > I open the library, then call dlsym to get the pointer to the procedure > > I want to call. That works fine. Then I call the procedure. Inside > > the library unit's exported function I call a function (register) in > > another unit that's in the uses clause. In the Register function of > > that unit I call RegisterComponents. This calls the function within > > creginst.inc unit. Because this is the first registration and the > > ComponentPages is not assigned it calls InitComponentPages. > > Somewhere within the TCollection.Create the funciton throws an exception. > > (and more specifically the heap manager) are not initialized. > > What I suggest you to do for the moment is to load the > 'FPC_INITIALIZEUNITS' > and run that. This will initialize the units in the library, and should > take care of the exception. > > A more fundamental problem is that the 'is' and 'as' functions will NOT > function correctly for objects generated by libraries. > > Why ? > Suppose you have an instantiated class from the library. The instance will > have a pointer to the class VMT, which resides in the library. The statement > > if Instance is TSomeClass Then > > Will see in the VMT of Instance whether TSomeClass (a pointer) is present > in the chain of ancestors. Since the ancestor VMT's of Instance reside all > in the library, and TSomeClass points to a VMT located somewhere in the > Lazarus executable, this will always return false. > > This problem exists also under Delphi, and can only be solved with EXPLICIT > Compiler/RTL support for packages, which Delphi has, and we don't. > > > > > Can someone look into that code and tell me if it's related to the dynamic > > linking or if it's simply an error in the InitComponentPages code? > > > > I really have been struggling trying to trace this down and would > > appreciate any help. > > The above is a rather lengthy explanation, but it is the only one I can > offer. > > Michael. > > _________________________________________________________________ > To unsubscribe: mail with > "unsubscribe" as the Subject > archives at http://www.miraclec.com/list_archives/lazarus >

Reply by email

Unknown author
to Shane Miller: In order to create Packages for Lazarus I am dynamically linking a unit into Lazarus. I…
Shane Miller wrote 14 lines
Greetings, In order to create Packages for Lazarus I am dynamically linking a unit into Lazarus. I am using the dl functions DLOpen, DLClose, DLSym to facilitate this. I open the library, then call dlsym to get the pointer to the procedure I want to call. That works fine. Then I call the procedure. Inside the library unit's exported function I call a function (register) in another unit that's in the uses clause. In the Register function of that unit I call RegisterComponents. This calls the function within creginst.inc unit. Because this is the first registration and the ComponentPages is not assigned it calls InitComponentPages. Somewhere within the TCollection.Create the funciton throws an exception.

(and more specifically the heap manager) are not initialized.

What I suggest you to do for the moment is to load the 'FPC_INITIALIZEUNITS'
and run that. This will initialize the units in the library, and should take care of the exception.

A more fundamental problem is that the 'is' and 'as' functions will NOT function correctly for objects generated by libraries.

Why ?
Suppose you have an instantiated class from the library. The instance will have a pointer to the class VMT, which resides in the library. The statement

if Instance is TSomeClass Then

Will see in the VMT of Instance whether TSomeClass (a pointer) is present in the chain of ancestors. Since the ancestor VMT's of Instance reside all in the library, and TSomeClass points to a VMT located somewhere in the Lazarus executable, this will always return false.

This problem exists also under Delphi, and can only be solved with EXPLICIT Compiler/RTL support for packages, which Delphi has, and we don't.

Show quoted text 6 lines
Can someone look into that code and tell me if it's related to the dynamic linking or if it's simply an error in the InitComponentPages code? I really have been struggling trying to trace this down and would appreciate any help.

The above is a rather lengthy explanation, but it is the only one I can offer.

Michael.

Reply by email

Shane Miller

Greetings,

In order to create Packages for Lazarus I am dynamically linking a unit into Lazarus. I am using the dl functions DLOpen, DLClose, DLSym to facilitate this.

I open the library, then call dlsym to get the pointer to the procedure I want to call. That works fine. Then I call the procedure. Inside the library unit's exported function I call a function (register) in another unit that's in the uses clause. In the Register function of that unit I call RegisterComponents. This calls the function within creginst.inc unit. Because this is the first registration and the ComponentPages is not assigned it calls InitComponentPages. Somewhere within the TCollection.Create the funciton throws an exception.

Can someone look into that code and tell me if it's related to the dynamic linking or if it's simply an error in the InitComponentPages code?

I really have been struggling trying to trace this down and would appreciate any help.

Thanks
Shane

Reply by email