[gmpi] Re: ABI's
- From: Chris Grigg <gmpi-public@xxxxxxxxxxxxxx>
- To: gmpi@xxxxxxxxxxxxx
- Date: Wed, 23 Feb 2005 12:13:45 -0800
Hi Jeff, thanks a lot for clarifying.
> when all any plug binding
really needs is a specific bundle of predefined function
pointers?
Hi Chris,
Well, that's what we settled on..
struct IGIMPI_Plugin
{
int (*func1)();
int (*func2)();
int (*func3)();
};
Each instance has a pointer to that.
Great, this looks good.
The pointer could be
called "pointer_to_my_functions", but at present it's called
"vtable".
I like the design, but this naming, I humbly suggest, is a mistake
because of the possibility of confusion with the C++ vtable.
This API code is C, not C++. There is no 'tricks' as
such.
At the risk of confusing the issue, the struct happens to
layout in memory just like a C++ class (on some compilers).
We are under no compulsion to perform any 'tricks' with
this. The technique stands up on it's own merits, purely
from a C standpoint.
Again, I agree the technique is sound, but because of its similarity
to the C++ runtime system we may want to take pains to disambiguate
the two via naming. And if any statements are made about direct
compatibility with any particular compiler(s) output, might be best
to make them soft and parenthetical.
>> jumps to jumps get optimized out by all modern HW
architectures anyway.
Not when the jump is into a dll. The compiler has no
foreknowlege of the ultimate destination.
Trace into a VST plugin, execution proceeds via the C
stub, into to C++ member function. We are doing *exactly*
the same thing.
I meant the processor execution pipeline optimization, not compiler
optimization.
> ..query function that the host calls repeatedly at
factory time to get all the function ptrs passed back,
one at a time, so that the host can build its own jump
table, rather than jumping through the plug's.
.. Don't know why we would choose to have all those
headaches both in initial development and over time, when
they could so easily be avoided.
We are exporting an ANSI C struct (POD plain old data). The
C ABI does not change. C structs are portable. There is no
issue. We do not change the GMPI API C struct, ever.
Again, excellent. Sorry for not understanding better. There has
been a lot of stressing the similarity to existing runtimes &
component architectures, I guess it just got me confused.
-- Chris G.
Best Regards,
Jeff
E.g.
gmpiFunctionOffset getFunctionOffset( gmpiPlugClassID
inPlugClass, gmpiApiFunctionID inFunctionID ) --
internally it's just a big, dead simple, switch(){}
statement. No tables needed.
Either way, you avoid both a) all the per-implementation
differences, and b) all the external change dependencies.
Don't know why we would choose to have all those
headaches both in initial development and over time, when
they could so easily be avoided.
Hi all, been monitoring off and on, and am glad to see so
much practical progress lately. Just wanted to inject an
idea before coding goes too much farther.
What I don't understand from a practical perspective is,
why are we talking about relying on other peoples' ABI
specs in the first place, when all any plug binding
really needs is a specific bundle of predefined function
pointers? (Offsets from start of plug package file
really, I guess.) The GMPI API is going to have a limited
, fixed number of functions, so even if there is broad
compiler and OS support for particular component
architectures like COM or DLL, doing actual symbol
linking at runtime a) is overkill, and furthermore b)
brings no clear benefits (can anyone name any?). Note that
, as somebody mentioned on the VST list a while ago,
jumps to jumps get optimized out by all modern HW
architectures anyway, so this discussion is all just
about plumbing, there's no efficiency argument.
The downsides of using other peoples' ABI formats are
obvious: they may be different for different platforms,
different for different compilers on a single platform --
> a developer's nightmare to keep them all straight -- and
even within a single platform and compiler the formats
might be changed by other people at unknowable point(s)
in the future, necessitating a rev in our spec, and
causing the entire plug inventory to need to be rebuilt
and redistributed -- for commercial plug houses, a huge
practical problem from a business perspective. All of
which is .completely. out of our control. In short, all
external ABI dependencies are vulnerabilities to randomly
timed unwanted catastrophic changes.
There are at least two alternatives. Either:
1) Define a single, very simple function ptr table format
for the start of all of GMPI plug package files, without
referencing, nor claiming to be binary-interoperable with
, any external ABI spec. Simple is the key.
or else:
2) Don't cache any function ptr table in the plug binary
at all, instead just have the plug package file publish a
query function (via an offset at a known offset into the
file, like 0 or 4) that the host calls repeatedly at
factory time to get all the function ptrs passed back,
one at a time, so that the host can build its own jump
table, rather than jumping through the plug's. E.g.
gmpiFunctionOffset getFunctionOffset( gmpiPlugClassID
inPlugClass, gmpiApiFunctionID inFunctionID ) --
internally it's just a big, dead simple, switch(){}
statement. No tables needed.
Either way, you avoid both a) all the per-implementation
differences, and b) all the external change dependencies.
Don't know why we would choose to have all those
headaches both in initial development and over time, when
they could so easily be avoided.
OK, going back to hide under my rock now...
-- Chris G.
----------------------------------------------------------
------------ Generalized Music Plugin Interface (GMPI)
public discussion list Participation in this list is
contingent upon your abiding by the following rules:
Please stay on topic. You are responsible for your own
words. Please respect your fellow subscribers. Please do
not redistribute anyone else's words without their
permission.
Archive: http://www.freelists.org/archives/gmpi
Email gmpi-request@xxxxxxxxxxxxx w/ subject "unsubscribe"
to unsubscribe
----------------------------------------------------------------------
Generalized Music Plugin Interface (GMPI) public discussion list
Participation in this list is contingent upon your abiding by the
following rules: Please stay on topic. You are responsible for your own
words. Please respect your fellow subscribers. Please do not
redistribute anyone else's words without their permission.
Archive: http://www.freelists.org/archives/gmpi
Email gmpi-request@xxxxxxxxxxxxx w/ subject "unsubscribe" to unsubscribe
----------------------------------------------------------------------
Generalized Music Plugin Interface (GMPI) public discussion list
Participation in this list is contingent upon your abiding by the
following rules: Please stay on topic. You are responsible for your own
words. Please respect your fellow subscribers. Please do not
redistribute anyone else's words without their permission.
Archive: http://www.freelists.org/archives/gmpi
Email gmpi-request@xxxxxxxxxxxxx w/ subject "unsubscribe" to unsubscribe
- Follow-Ups:
- [gmpi] Re: ABI's
- From: Jeff McClintock
- [gmpi] Re: ABI's
- From: Tim Hockin
- References:
- [gmpi] Re: ABI's
- From: jeffmcc
Other related posts:
- » [gmpi] ABI's
- » [gmpi] Re: ABI's
- » [gmpi] Re: ABI's
- » [gmpi] Re: ABI's
- » [gmpi] Re: ABI's
- » [gmpi] Re: ABI's
- » [gmpi] Re: ABI's
- » [gmpi] Re: ABI's
- » [gmpi] Re: ABI's
- » [gmpi] Re: ABI's
- » [gmpi] Re: ABI's
really needs is a specific bundle of predefined function
pointers?
Hi Chris, Well, that's what we settled on..
struct IGIMPI_Plugin
{
int (*func1)();
int (*func2)();
int (*func3)();
};Each instance has a pointer to that.
Great, this looks good.
The pointer could be called "pointer_to_my_functions", but at present it's called "vtable".
This API code is C, not C++. There is no 'tricks' as such. At the risk of confusing the issue, the struct happens to layout in memory just like a C++ class (on some compilers).
We are under no compulsion to perform any 'tricks' with this. The technique stands up on it's own merits, purely from a C standpoint.
architectures anyway.
Not when the jump is into a dll. The compiler has no foreknowlege of the ultimate destination. Trace into a VST plugin, execution proceeds via the C stub, into to C++ member function. We are doing *exactly* the same thing.
factory time to get all the function ptrs passed back, one at a time, so that the host can build its own jump table, rather than jumping through the plug's. .. Don't know why we would choose to have all those headaches both in initial development and over time, when they could so easily be avoided.
We are exporting an ANSI C struct (POD plain old data). The C ABI does not change. C structs are portable. There is no issue. We do not change the GMPI API C struct, ever.
Best Regards, Jeff
E.g.
gmpiFunctionOffset getFunctionOffset( gmpiPlugClassID inPlugClass, gmpiApiFunctionID inFunctionID ) -- internally it's just a big, dead simple, switch(){} statement. No tables needed.
Either way, you avoid both a) all the per-implementation differences, and b) all the external change dependencies. Don't know why we would choose to have all those headaches both in initial development and over time, when they could so easily be avoided.
> a developer's nightmare to keep them all straight -- and
Hi all, been monitoring off and on, and am glad to see so much practical progress lately. Just wanted to inject an idea before coding goes too much farther.
What I don't understand from a practical perspective is, why are we talking about relying on other peoples' ABI specs in the first place, when all any plug binding really needs is a specific bundle of predefined function pointers? (Offsets from start of plug package file really, I guess.) The GMPI API is going to have a limited , fixed number of functions, so even if there is broad compiler and OS support for particular component architectures like COM or DLL, doing actual symbol linking at runtime a) is overkill, and furthermore b) brings no clear benefits (can anyone name any?). Note that , as somebody mentioned on the VST list a while ago, jumps to jumps get optimized out by all modern HW architectures anyway, so this discussion is all just about plumbing, there's no efficiency argument.
The downsides of using other peoples' ABI formats are obvious: they may be different for different platforms, different for different compilers on a single platform --
even within a single platform and compiler the formats might be changed by other people at unknowable point(s) in the future, necessitating a rev in our spec, and causing the entire plug inventory to need to be rebuilt and redistributed -- for commercial plug houses, a huge practical problem from a business perspective. All of which is .completely. out of our control. In short, all external ABI dependencies are vulnerabilities to randomly timed unwanted catastrophic changes.
There are at least two alternatives. Either:
1) Define a single, very simple function ptr table format for the start of all of GMPI plug package files, without referencing, nor claiming to be binary-interoperable with , any external ABI spec. Simple is the key.
or else:
2) Don't cache any function ptr table in the plug binary at all, instead just have the plug package file publish a query function (via an offset at a known offset into the file, like 0 or 4) that the host calls repeatedly at factory time to get all the function ptrs passed back, one at a time, so that the host can build its own jump table, rather than jumping through the plug's. E.g. gmpiFunctionOffset getFunctionOffset( gmpiPlugClassID inPlugClass, gmpiApiFunctionID inFunctionID ) -- internally it's just a big, dead simple, switch(){} statement. No tables needed.
Either way, you avoid both a) all the per-implementation differences, and b) all the external change dependencies. Don't know why we would choose to have all those headaches both in initial development and over time, when they could so easily be avoided.
OK, going back to hide under my rock now...
-- Chris G.
---------------------------------------------------------- ------------ Generalized Music Plugin Interface (GMPI) public discussion list Participation in this list is contingent upon your abiding by the following rules: Please stay on topic. You are responsible for your own words. Please respect your fellow subscribers. Please do not redistribute anyone else's words without their permission.
Archive: http://www.freelists.org/archives/gmpi Email gmpi-request@xxxxxxxxxxxxx w/ subject "unsubscribe" to unsubscribe
---------------------------------------------------------------------- Generalized Music Plugin Interface (GMPI) public discussion list Participation in this list is contingent upon your abiding by the following rules: Please stay on topic. You are responsible for your own words. Please respect your fellow subscribers. Please do not redistribute anyone else's words without their permission.
Archive: http://www.freelists.org/archives/gmpi Email gmpi-request@xxxxxxxxxxxxx w/ subject "unsubscribe" to unsubscribe
- [gmpi] Re: ABI's
- From: Jeff McClintock
- [gmpi] Re: ABI's
- From: Tim Hockin
- [gmpi] Re: ABI's
- From: jeffmcc