Sign in Join

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

Mailing lists / fpc-pascal / 2019-10

Dynamic loading to static?

8 messages · 3 people · –

Reply by email Subscribe to this list Your subscription

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

Ryan Joseph

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

Reply by email

Michael Van Canneyt
to Ryan Joseph
Ryan Joseph wrote 13 lines
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.

Reply by email

Ryan Joseph
to Michael Van Canneyt
Show quoted text 6 lines
On Oct 25, 2019, at 12:02 PM, Michael Van Canneyt 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

Reply by email

Sven Barth
to Ryan Joseph
Ryan Joseph wrote 15 lines
> On Oct 25, 2019, at 12:02 PM, Michael Van Canneyt 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

Reply by email

Ryan Joseph
to Sven Barth
On Oct 26, 2019, at 4:26 AM, Sven Barth via fpc-pascal 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

Reply by email

Sven Barth
to Ryan Joseph
Ryan Joseph wrote 7 lines
> On Oct 26, 2019, at 4:26 AM, Sven Barth via fpc-pascal 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

Reply by email

Ryan Joseph
to Sven Barth
Show quoted text 7 lines
On Oct 26, 2019, at 12:55 PM, Sven Barth via fpc-pascal 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

Reply by email

Sven Barth
to Ryan Joseph

Ryan Joseph schrieb am Sa., 26. Okt. 2019, 22:46:

Show quoted text 15 lines
> On Oct 26, 2019, at 12:55 PM, Sven Barth via fpc-pascal < > 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

Reply by email