Dynamic loading to static?

classic Classic list List threaded Threaded
8 messages Options
Reply | Threaded
Open this post in threaded view
|

Dynamic loading to static?

Ryan Joseph-2
Maybe a stupid question but I thought I’d asked before I potentially waste a bunch of time. I have code to dynamically load functions using Dynlibs.LoadLibrary, for example:

type
  _Py_Initialize = procedure; cdecl;
  _PyImport_ImportModule = function(module: pchar): PPyObject; cdecl;

var
  […]
  Py_Initialize := _Py_Initialize(GetProcAddress(handle, 'Py_Initialize'));

The problem is I would like to change this to static linking now but I only have function pointers instead of declarations. Is there a way I can get the compiler to statically link these function pointers or do I need to manually change them all by hand to be things like:

        function  PyImport_ImportModule(module: pchar): PPyObject; cdecl;

Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Dynamic loading to static?

Michael Van Canneyt


On Fri, 25 Oct 2019, Ryan Joseph wrote:

> Maybe a stupid question but I thought I’d asked before I potentially waste a bunch of time. I have code to dynamically load functions using Dynlibs.LoadLibrary, for example:
>
> type
>  _Py_Initialize = procedure; cdecl;
>  _PyImport_ImportModule = function(module: pchar): PPyObject; cdecl;
>
> var
>  […]
>  Py_Initialize := _Py_Initialize(GetProcAddress(handle, 'Py_Initialize'));
>
> The problem is I would like to change this to static linking now but I only have function pointers instead of declarations. Is there a way I can get the compiler to statically link these function pointers or do I need to manually change them all by hand to be things like:
>
> function  PyImport_ImportModule(module: pchar): PPyObject; cdecl;
You need to manually change them.

if you look in the packages, you'll see that many library import units exist in 2
flavours. One static, one dynamic.

Michael.
_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Dynamic loading to static?

Ryan Joseph-2


> On Oct 25, 2019, at 12:02 PM, Michael Van Canneyt <[hidden email]> wrote:
>
> You need to manually change them.
>
> if you look in the packages, you'll see that many library import units exist in 2
> flavours. One static, one dynamic.

That’s what I was afraid of.

btw, I why does ObjFPC mode not allow this but Delphi mode does? GetProcAddress returns a pointer and I get a type error which can’t be solved because the type of Py_Initialize  is anonymous, i.e. there is no formal declaration. Is there a way to cast around this in ObjFPC mode? It would be lots of extra work to add the extra types in because the original code was Delphi.

var
    Py_Initialize: procedure; cdecl;
begin
    Py_Initialize := GetProcAddress(handle, 'Py_Initialize');

Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Dynamic loading to static?

Free Pascal - General mailing list
Am 25.10.2019 um 20:49 schrieb Ryan Joseph:

>
>> On Oct 25, 2019, at 12:02 PM, Michael Van Canneyt <[hidden email]> wrote:
>>
>> You need to manually change them.
>>
>> if you look in the packages, you'll see that many library import units exist in 2
>> flavours. One static, one dynamic.
> That’s what I was afraid of.
>
> btw, I why does ObjFPC mode not allow this but Delphi mode does? GetProcAddress returns a pointer and I get a type error which can’t be solved because the type of Py_Initialize  is anonymous, i.e. there is no formal declaration. Is there a way to cast around this in ObjFPC mode? It would be lots of extra work to add the extra types in because the original code was Delphi.
>
> var
>      Py_Initialize: procedure; cdecl;
> begin
>      Py_Initialize := GetProcAddress(handle, 'Py_Initialize');
The FPC modes are simply more stricter, more like the original Pascal in
that case. After all a Pointer is not simply a procedure variable.

For your case you can solve it like this:

=== code begin ===

CodePointer(Py_Initialize) := GetProcAddress(handle, 'Py_Initialize');

=== code end ===

Regards,
Sven
_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Dynamic loading to static?

Ryan Joseph-2


> On Oct 26, 2019, at 4:26 AM, Sven Barth via fpc-pascal <[hidden email]> wrote:
>
> CodePointer(Py_Initialize) := GetProcAddress(handle, 'Py_Initialize');

Thanks that works.

I don’t think I’ve ever cast a left side value before in Pascal and honestly I didn’t think it was even possible. In fact didn’t we just have a big talk about for loop iterators and how they can’t be type cast? I thought that was because casting the left side value was illegal. Very confused now. ;)

Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Dynamic loading to static?

Free Pascal - General mailing list
Am 26.10.2019 um 14:56 schrieb Ryan Joseph:
>
>> On Oct 26, 2019, at 4:26 AM, Sven Barth via fpc-pascal <[hidden email]> wrote:
>>
>> CodePointer(Py_Initialize) := GetProcAddress(handle, 'Py_Initialize');
> Thanks that works.
>
> I don’t think I’ve ever cast a left side value before in Pascal and honestly I didn’t think it was even possible. In fact didn’t we just have a big talk about for loop iterators and how they can’t be type cast? I thought that was because casting the left side value was illegal. Very confused now. ;)
The for-in loop works *because* casting the left side of an assignment
is legal. If it wouldn't be legal there wouldn't have been any
discussion, because then the bug wouldn't be there. The compiler simply
transforms

=== code begin ===

for x in y do begin
   // ...
end;

=== code end ===

into

=== code begin ===

tmpenum := y.GetEnumerator;
while tmpenum.MoveNext do begin
   x := tmpenum.Current;
   // ...
end;

=== code end ===

Thus "for cast(x) in y" simply becomes the ordinary assignment "cast(x)
:= tmpenum.Current", which is why the compiler does not complain currently.

However a for-loop does not have an assignment in the usual sense for
the loop-variable, thus the following is not legal:

=== code begin ===

var
   i: smallint;
begin
   for word(i) := 0 to 15 do ;
end.

=== code end ===

Regards,
Sven
_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Dynamic loading to static?

Ryan Joseph-2


> On Oct 26, 2019, at 12:55 PM, Sven Barth via fpc-pascal <[hidden email]> wrote:
>
> tmpenum := y.GetEnumerator;
> while tmpenum.MoveNext do begin
>   x := tmpenum.Current;
>   // ...
> end;

Ok, I understand how you guys are seeing this now. I wasn’t thinking of it as a while loop so casting just made sense to me from an efficiency standpoint.

Regards,
        Ryan Joseph

_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal
Reply | Threaded
Open this post in threaded view
|

Re: Dynamic loading to static?

Free Pascal - General mailing list
Ryan Joseph <[hidden email]> schrieb am Sa., 26. Okt. 2019, 22:46:


> On Oct 26, 2019, at 12:55 PM, Sven Barth via fpc-pascal <[hidden email]> wrote:
>
> tmpenum := y.GetEnumerator;
> while tmpenum.MoveNext do begin
>   x := tmpenum.Current;
>   // ...
> end;

Ok, I understand how you guys are seeing this now. I wasn’t thinking of it as a while loop so casting just made sense to me from an efficiency standpoint.

As said in the other thread, use absolute to avoid the explicit cast. 

Regards, 
Sven 

_______________________________________________
fpc-pascal maillist  -  [hidden email]
https://lists.freepascal.org/cgi-bin/mailman/listinfo/fpc-pascal