Recent

Author Topic: Passing parameters to library  (Read 21352 times)

micha.schumann

  • New member
  • *
  • Posts: 8
Passing parameters to library
« on: February 20, 2010, 11:40:42 am »
Hello,

i am currently designing a plugin based system where all plugins need heavy interfaces to the host and vice versa. In either plugins and host I implement interfaces (with GUID) and pass them to the dll (host object interface) and back (plugin object interface). This works good (I did this in delphi once for a product that runs for 10 years in the field), when using pChar as parameters and return values. Since I assign a object to an Interface I had to swicht to delphi mode.

Unfortunately I run into problems when I try to pass e.g. a query object to the plugin and run a query there. If i have an error in the query sql, the system gracefully states an SQL error, so the library can obviously access the query object. But it the sql is correct and I try to access a field value, I get an SIGSEGV.

In delphi 7 I can pass everything from and to my plugins after having included a special memory manager. I think this is not necessary with FPC/Lazarus?

Most likely there is something trivial I have missed and I would be very grateful for any tips!

micha

Leledumbo

  • Hero Member
  • *****
  • Posts: 8785
  • Programming + Glam Metal + Tae Kwon Do = Me
Re: Passing parameters to library
« Reply #1 on: February 22, 2010, 11:59:00 am »
General rule in using libraries: never pass compiler managed types to library routines (objects, classes, strings except pchar, etc).

micha.schumann

  • New member
  • *
  • Posts: 8
Re: Passing parameters to library
« Reply #2 on: February 24, 2010, 01:00:27 pm »
Thanks.

I wonder why I cannot pass a pointer to a structure (object) that is equally defined in both host and plugin since both are written in fpc/lazarus. If I can pass a PChar that points to a string both sides have agreed on that kind of structure, shouldnt that work with objects too?

In delphi 7 I passed any kind of objects between plugin and host and vice versa which is cool since the plugin can use all the database objects of the host what icreases speed. I need that speed since the plugins will be called very often using a DB connection in a more or less time critical environment and they have to do complicated stuff.

I can imagine reducing all this to only using pChar but I would like to understand why passing objects (what IMO are pointers to objects) is not possible.

Excuse me, if this is a dumb question. I never dived this deep into those internals, maybe I should have and know the answer as as someone having started with pascal on my ZX Spectrum nearly 25 Years ago... Please also excuse my English, this is not my native language.

Marc

  • Administrator
  • Hero Member
  • *
  • Posts: 2623
Re: Passing parameters to library
« Reply #3 on: February 24, 2010, 02:29:17 pm »
In Delphi it just happens to work.

When passing instances of a class, you assume that both your exe and your dll used the same RTL definition of it. In a normal program, when you do a class check like "if myobj is TObject ..." you compare both VMT entries. However since a program and a dll are 2 separate exes, they have each their own instance of TObject, so both VMT addresses are different, so the given check will fail.

Another thing is the global variables the LCL implements like Application, Screen etc. Your dll has them too and they don't point to the same instance. IIRC delphi has some tricks to link them, so the dll application loop is run in the program application loop etc.

So as general rule of thumb, don't pass them.
//--
{$I stdsig.inc}
//-I still can't read someones mind
//-Bugs reported here will be forgotten. Use the bug tracker

marcov

  • Administrator
  • Hero Member
  • *
  • Posts: 12033
  • FPC developer.
Re: Passing parameters to library
« Reply #4 on: February 24, 2010, 02:32:40 pm »

Another thing is the global variables the LCL implements like Application, Screen etc. Your dll has them too and they don't point to the same instance. IIRC delphi has some tricks to link them, so the dll application loop is run in the program application loop etc.

Dlls or packages under Delphi?

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1930
Re: Passing parameters to library
« Reply #5 on: February 24, 2010, 02:33:44 pm »
Doesn't this have to do with Delphi's Sharemem?

Micha, you speak german, right?
http://entwickler-forum.de/showthread.php?t=24744

Marc

  • Administrator
  • Hero Member
  • *
  • Posts: 2623
Re: Passing parameters to library
« Reply #6 on: February 24, 2010, 02:36:09 pm »
No both issues I pointed at aren't solved by a shared memory manager.

They will if you use a package as dll
//--
{$I stdsig.inc}
//-I still can't read someones mind
//-Bugs reported here will be forgotten. Use the bug tracker

theo

  • Global Moderator
  • Hero Member
  • *****
  • Posts: 1930
Re: Passing parameters to library
« Reply #7 on: February 24, 2010, 02:54:58 pm »
No both issues I pointed at aren't solved by a shared memory manager.

Right. But it would work for passing AnsiString etc. or what's the purpose of Sharemem?

micha.schumann

  • New member
  • *
  • Posts: 8
Re: Passing parameters to library
« Reply #8 on: February 24, 2010, 09:19:02 pm »
I speak german  :D and will have a look at that thread. Thanks.

In my Delphi app I use DLLs as Plugins (based on the jvcl Plugins) and fastMM4 instead of sharemem. In both DLL and Host I implement interfaces and pass those between the host and plugin. This works absolutely stable for nearly 10 years now.

But the shared memory manager cant be the key since in Delphi without it you cannot pass pChar only short strings and integers.

I would like to develop a flexible plugin infrastructure for lazarus and share it, I am sure others could use that too. If there is any (platform independant) approach I could try, please share your ideas.

Thanks,

Micha


Marc

  • Administrator
  • Hero Member
  • *
  • Posts: 2623
Re: Passing parameters to library
« Reply #9 on: February 25, 2010, 10:57:31 am »
No both issues I pointed at aren't solved by a shared memory manager.

Right. But it would work for passing AnsiString etc. or what's the purpose of Sharemem?

Correct. And for dyn arrays. These types are freed using the "local" memory manager
//--
{$I stdsig.inc}
//-I still can't read someones mind
//-Bugs reported here will be forgotten. Use the bug tracker

Zaher

  • Hero Member
  • *****
  • Posts: 683
    • parmaja.org
Re: Passing parameters to library
« Reply #10 on: February 25, 2010, 12:59:05 pm »
in Delphi it is enough the share the package rtl100.bpl, in FreePascal dynamic packages not implemented yet, may be only the rtl of freepascal can make it dynamic and use it with all plugins.

micha.schumann

  • New member
  • *
  • Posts: 8
Re: Passing parameters to library
« Reply #11 on: February 25, 2010, 07:22:09 pm »
I forgot to mention that I do not use any dynamic package loading in delphi. I compile dll and exe without any runtime dlls/packages so they share nothing except for the FastMM4 memory manager assigned space.

Is it really true that a pointer to a structure in the exe is not valid in the dll when pointing to exactly the same structure? In my understanding a "object" in eiter delphi and fp is a pointer so a record of method pointers and elements. Where is the difference between the pointer to e.g. a DB object if I pass it to the dll and assign it to a DB Object?

What I dont get here is the difference between delphi 7 and FPC at this point when not using shared runtime packages etc. It definitively works great in delhpi 7 the way I sketched it. For me this feature is essential to build plugin extendable systems. Passing pChars isnt really powerful and causes a lot of overhead.

Thanks for your patience with an 48 year old ignorant ;-)

Marc

  • Administrator
  • Hero Member
  • *
  • Posts: 2623
Re: Passing parameters to library
« Reply #12 on: February 26, 2010, 11:12:35 am »
Is it really true that a pointer to a structure in the exe is not valid in the dll when pointing to exactly the same structure?
The pointer is valid. But the question is how exactly the same the structure is.

Quote
In my understanding a "object" in eiter delphi and fp is a pointer so a record of method pointers and elements. Where is the difference between the pointer to e.g. a DB object if I pass it to the dll and assign it to a DB Object?

Ehm... there are objects and there are objects.
Sometimes and instance of a class is called object (type = class) and you have record like objects (type = object). Both are indeed some record with members and method pointers. And, for an exe and dll, if they are comiled with the same version, their layout is the same.
However, with a class you can do more. For instance you can ask a class if it descends form a certain class like:
Code: Pascal  [Select][+][-]
  1. if MyForm is TForm then DoSomething
How does this work ?
One of the members (the first iirc) of the instance of a class "record" is a pointer to the class definition. This pointer is compared to see if something is the same class.
For your exe and dll, this pointer points to their own a piece of readonly memory, part of your exe or dll. So when comparing a class instance created in your exe with one created in your dll, the "is" operator will fail.

This is just one of the problems. However, when you only call some methods of it, they usually will work, unless they modify some internal dynamic type (like a string) and you don't have a shared memorymanager
//--
{$I stdsig.inc}
//-I still can't read someones mind
//-Bugs reported here will be forgotten. Use the bug tracker

micha.schumann

  • New member
  • *
  • Posts: 8
Re: Passing parameters to library
« Reply #13 on: March 02, 2010, 04:59:41 pm »
So if understand correctly, it should work unless I compare types of objects.

If I pass a pointer to a eg TQuery object to the dll and assign this pointer to a TQuery object (same compiler, same libraries) defined in the dll it should work.

So we are near the beginning of the post. Passing this to the dll worked, if the query had an error, I got a clean SQL error message from the dll. So it executed the query and received the error message from the server. If the statement was querying a valid result, the system crashed. So maybe the problem is located somewhere else - it could in fact have to do with shareing memory or not?

As soon I have a bit more time, I will perepare an example of the plugin interface I designed. Perhaps a pro sees the error immediately. Currently the code is kind of chaotic.

Marc

  • Administrator
  • Hero Member
  • *
  • Posts: 2623
Re: Passing parameters to library
« Reply #14 on: March 03, 2010, 10:06:55 am »
So if understand correctly, it should work unless I compare types of objects.
It's just one of the things I could think of, there might be other issues

Quote
If I pass a pointer to a eg TQuery object to the dll and assign this pointer to a TQuery object (same compiler, same libraries) defined in the dll it should work.

So we are near the beginning of the post. Passing this to the dll worked, if the query had an error, I got a clean SQL error message from the dll. So it executed the query and received the error message from the server. If the statement was querying a valid result, the system crashed. So maybe the problem is located somewhere else - it could in fact have to do with shareing memory or not?
Most likely yes. The object might contain strings allocated in the application and on a successful result be replaced by strings allocated in the dll.
Also I don't know if a TQuery does, for instance, some type comparison on the resulting fields internally (which may fail)

Quote
As soon I have a bit more time, I will perepare an example of the plugin interface I designed. Perhaps a pro sees the error immediately. Currently the code is kind of chaotic.
//--
{$I stdsig.inc}
//-I still can't read someones mind
//-Bugs reported here will be forgotten. Use the bug tracker

 

TinyPortal © 2005-2018