Thread overview | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
March 19, 2004 Separating implementation from definition | ||||
---|---|---|---|---|
| ||||
I've struggled with this for a few hours now, and admit defeat.
I'd like to be able to have a file that defines a class's public interface AND the class name, but not contain the implementation code. I'd like to do this so I can distribute the class definition and an .OBJ file, but without distributing the implementation code.
I thought I could define an interface to do this but that isn't quite right either, as all that does is specify a set of member functions, and has nothing to do with a class Name etc.
Here is what I'd like to do ...
In a file called 'foo_defn.d' I'd have ...
// The publicly exposed API for the Foo class.
class Foo definition
{
this();
this(int pValue);
~this();
int TheValue();
void TheValue(int pValue);
}
And in another file 'foo.d' I'd have ...
import foo_defn;
class Foo implementation
{
int v_TheValue;
this() {v_TheValue = 1;}
...etc...
}
I would then compile 'foo.d' to create 'foo.obj'. Then I would distribute 'foo.obj' and 'foo_defn.d' so that somebody else could create a file such as 'myfoo.d' ...
import foo_defn;
class MyFoo
{
Foo f;
this() { f = new Foo;}
...etc...
}
They would then compile 'myfoo.d' and link in 'foo'obj'. This way, they could use my foo class without knowing how it was implemented.
This all seems so basic to me that I'm sure I've missed something dead obvious.
--
Derek
|
March 19, 2004 Re: Separating implementation from definition | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Derek Parnell wrote:
> I've struggled with this for a few hours now, and admit defeat.
>
> I'd like to be able to have a file that defines a class's public interface AND the class name, but not contain the implementation code. I'd like to do this so I can distribute the class definition and an .OBJ file, but without distributing the implementation code.
>
> I thought I could define an interface to do this but that isn't quite right either, as all that does is specify a set of member functions, and has nothing to do with a class Name etc.
>
<sip>
I fail to see why a separate public interface is needed. The way I understood it was that D simpifies the work with its import. You just provide your object file and appropriate documentation so that your user knows how to access the public class details. Documentation amounts to the same thing as a the separate class interface anyway. You have fewer source files to worry about as well, meaning less chance of creating inconsistancies between the interface and the implementation (although you could still make mistakes in the documentation too ;-D ).
Or maybe I'm not seeing things straight...
Take care,
John
|
March 19, 2004 Re: Separating implementation from definition | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | Check out the example in phobos for gc.d. There are two; one is the interface, the other is the definition. "Derek Parnell" <Derek.Parnell@psyc.ward> wrote in message news:opr43anbhtu2m3b2@news.digitalmars.com... > I've struggled with this for a few hours now, and admit defeat. > > I'd like to be able to have a file that defines a class's public interface AND the class name, but not contain the implementation code. I'd like to do this so I can distribute the class definition and an .OBJ file, but without distributing the implementation code. > > I thought I could define an interface to do this but that isn't quite right either, as all that does is specify a set of member functions, and has nothing to do with a class Name etc. > > Here is what I'd like to do ... > > In a file called 'foo_defn.d' I'd have ... > // The publicly exposed API for the Foo class. > class Foo definition > { > this(); > this(int pValue); > ~this(); > int TheValue(); > void TheValue(int pValue); > } > > And in another file 'foo.d' I'd have ... > > import foo_defn; > class Foo implementation > { > int v_TheValue; > this() {v_TheValue = 1;} > ...etc... > } > > I would then compile 'foo.d' to create 'foo.obj'. Then I would distribute 'foo.obj' and 'foo_defn.d' so that somebody else could create a file such as 'myfoo.d' ... > > import foo_defn; > class MyFoo > { > Foo f; > this() { f = new Foo;} > ...etc... > } > > They would then compile 'myfoo.d' and link in 'foo'obj'. This way, they could use my foo class without knowing how it was implemented. > > > This all seems so basic to me that I'm sure I've missed something dead obvious. > -- > Derek |
March 19, 2004 Re: Separating implementation from definition | ||||
---|---|---|---|---|
| ||||
Posted in reply to Walter | "Walter" <walter@digitalmars.com> wrote in message news:c3e7hl$l03$2@digitaldaemon.com... > Check out the example in phobos for gc.d. There are two; one is the interface, the other is the definition. There are two whats? Two files called 'gc.d'? Two examples? If so what are their file names? I really do not know what you are talking about. I found a file called gc.d in the folder 'phobus\std', all that contains is a collection of function templates - nothing to do with classes in there though. And I found a file called 'gcstats.d' in the folder 'phobus', but that just contains a structure definition - again no classes. Maybe I'm not explaining myself clearly enough. Sorry about that. I'll have another go... I want to enable a third party to use a CLASS that I have created, but I do not want to give that person the source code to my class's implementation. As I see it, to do that the person will need to have the OBJ file that I would supply. However, if that person is to refer to my class in their own source code, the D compiler needs to have a source definition of my class too. So the question is simply this -- How can I write a source code file that exposes the public API for my class, without exposing the implemention code? At first, I thought that the D interface concept would be just the thing. So I tried this... I created a file called 'Foo_i.d" that contained... interface i_Foo { int FuncA(); int FuncB(); ...etc... } Hoping that all the third party need to do then was to use this file thus ... import Foo_i; class SuperFoo: i_Foo { . . . } But all this meant was that now they had to implement FuncA, FuncB, etc... Not what I wanted! Next I created the file 'foo_i.d' that contained my complete class definition AND implementation code. I compiled that to get a OBJ file 'foo_i.obj'. I renamed that to 'foo.obj'. Then I create a file 'foo.d' that only had the parts of my Foo class that I wished to expose - some functions (not all) and none of the class's variables. Then I pretended to be the third party wishing to use the Foo class. So I create a file 'sfoo.d' that looked like this ... import foo; class SuperFoo: Foo { int FuncC(){return 1;} } This compiled okay, picking up my cut-down version of Foo's definition (from importing 'foo'). I then created 'test.d' with this ... import sfoo; void main() { SuperFoo a; a = new SuperFoo; a.FuncA(); a.FuncC(); } This also compiled okay. But it wouldn't link correctly. The functions that I exposed in my foo.d and the class Foo itself were all undefined. So then I changed 'sfoo.d' so it would import 'foo_i' rather than 'foo' then recompiled 'test.d' and it compiled and linked okay. NOt surprising as 'foo_i.d' contains my implementation code as well as the class API definition. So this is my problem. I don't want to distribute foo_i.d, the one with my class implementation code. Just documenting the Foo API is not enough. Sure it needs to be done, but that doesn't avoid the need for the third party to have the source code for the Foo class (including implementation code). I hope what I want to do is a bit clearer now. -- Derek > "Derek Parnell" <Derek.Parnell@psyc.ward> wrote in message news:opr43anbhtu2m3b2@news.digitalmars.com... > > I've struggled with this for a few hours now, and admit defeat. > > > > I'd like to be able to have a file that defines a class's public interface > > AND the class name, but not contain the implementation code. I'd like to do this so I can distribute the class definition and an .OBJ file, but without distributing the implementation code. > > > > I thought I could define an interface to do this but that isn't quite right either, as all that does is specify a set of member functions, and has nothing to do with a class Name etc. > > > > Here is what I'd like to do ... > > > > In a file called 'foo_defn.d' I'd have ... > > // The publicly exposed API for the Foo class. > > class Foo definition > > { > > this(); > > this(int pValue); > > ~this(); > > int TheValue(); > > void TheValue(int pValue); > > } > > > > And in another file 'foo.d' I'd have ... > > > > import foo_defn; > > class Foo implementation > > { > > int v_TheValue; > > this() {v_TheValue = 1;} > > ...etc... > > } > > > > I would then compile 'foo.d' to create 'foo.obj'. Then I would distribute > > 'foo.obj' and 'foo_defn.d' so that somebody else could create a file such > > as 'myfoo.d' ... > > > > import foo_defn; > > class MyFoo > > { > > Foo f; > > this() { f = new Foo;} > > ...etc... > > } > > > > They would then compile 'myfoo.d' and link in 'foo'obj'. This way, they could use my foo class without knowing how it was implemented. > > > > > > This all seems so basic to me that I'm sure I've missed something dead obvious. > > -- > > Derek > > |
March 19, 2004 Re: Separating implementation from definition | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derjo Phar | Derjo Phar wrote:
> "Walter" <walter@digitalmars.com> wrote in message
> news:c3e7hl$l03$2@digitaldaemon.com...
>
>>Check out the example in phobos for gc.d. There are two; one is the
>>interface, the other is the definition.
>
>
> There are two whats? Two files called 'gc.d'? Two examples? If so what are
> their file names? I really do not know what you are talking about. I found a
> file called gc.d in the folder 'phobus\std', all that contains is a
> collection of function templates - nothing to do with classes in there
> though. And I found a file called 'gcstats.d' in the folder 'phobus', but
> that just contains a structure definition - again no classes.
The garbage collector source is in /dmd/src/phobos/internal/gc
'std' is just one of three directories in the phobos directory.
Cheers,
Sigbjørn Lund Olsen
|
March 20, 2004 Re: Separating implementation from definition | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derjo Phar | I understand what you are saying, and I apologize for my rather quick, non-thinking reply. You are right. It can't be done the way I said. I think this has been discussed before, and I agree it's an important issue. The DMD compiler seems to be more suited for open source projects currently. But it does link to external C object files with the extern attribute and export directive, so I would think that there is a way to interface with external D object files as well. I've just never had to worry or deal with that particular problem. Have you tried searching this newsgroup for past posts on this topic? Later, John |
March 20, 2004 Re: Separating implementation from definition | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derjo Phar | These topics have been discussed before. And Walter has gone into more detail in previous threads. A method of doing something like this is shown in the gc. You just have to dig far enough. This actually would be a very good topic for a tutorial, though. This thread in particular is pertanent and detailed: "Implementing extern methods" http://www.digitalmars.com/drn-bin/wwwnews?D/19210 Also, it's always a good idea to check for information on http://www.prowiki.org/wiki4d/wiki.cgi?FrontPage Hope that helps, John |
March 20, 2004 Re: Separating implementation from definition | ||||
---|---|---|---|---|
| ||||
Posted in reply to Derek Parnell | I hope this is what you were looking for: Here’s a quick tutorial for setting up an interface file and and implementation file. (I apologize about formatting... might turn up very bad in the newsgroup). STEP 1: Create your implementation file: /* -------------------------------------- */ module foo; import std.c.stdio; class Foo { public: int funcA() { printf(“Inside method implementation funcA of class Foo”); return 1; } int funcB() { printf(“Inside method implementation funcB of class Foo”); return 2; } } /* ----- end of implementation file ----- */ STEP 2: Compile the implementation file in a separate directory (your work directory for the project): dmd -c foo.d This should produce foo.obj. Move to another directory of your choice. This will be a directory that contains a project that will make use of the foo implementation. You will be providing an “interface” module that will allow the user to only see the public members of the class. So in this directory there will be: /* -------------------------------------- */ /* This module must be of the SAME NAME as the implementation module because of the way symbols are combined with the module name. */ module foo; class Foo { public: int funcA(); int funcB(); } /* ---------- end of interface module -------- */ The interface module is the file you will provide along with the foo.obj (implementation) to the developer. You do not compile this foo.d. It will be imported into the external developers project. An example: /* --- main project --- */ module project; import foo; int main( char[][] args ) { int a, b; Foo Foo1 = new Foo; printf("\nStarting from main():\n"); a=Foo1.funcA(); b=Foo1.funcB(); printf("\na = %d, b = %d\n", a, b); return 1; } The developer will then compile the project like so (making sure that the interface module and implementation object file are in the same directory; if they are not, remember to specify the correct paths): dmd project.d foo.obj -of project.exe The provided implementation is linked in with the project. The developer never sees the implementation details. Thanks to Walter for the for the gc reference ;-). Feel free to point any errors. I'm supposed to be busy studying for an exam... obviously I got sidetracked :-). Later, John |
March 20, 2004 Re: Separating implementation from definition | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Reimer | John Reimer wrote: > You just have to dig far enough. dig being a keyword here. Dig separates the implementation from definition using doxygen and by compiling to a lib. -- -Anderson: http://badmama.com.au/~anderson/ |
March 20, 2004 Re: Separating implementation from definition | ||||
---|---|---|---|---|
| ||||
Posted in reply to John Reimer | "John Reimer" <jjreimer@telus.net> wrote in message news:c3gnjg$1s5f$1@digitaldaemon.com... > I hope this is what you were looking for: Thank you John. Yes this is exactly it. I was almost there too. The only difference between the correct way you have shown and the way I was doing it, was that in the correct way there is the line 'module foo;' at the start of both the definition file and the implementation file. When I was doing it, I did not have that line or any 'module' statement at all. I guess I didn't really understand the purpose of the module statement. It seems that this identifies the namespace for the file, and if not supplied, the namespace is the same as the file name. -- Derek |
Copyright © 1999-2021 by the D Language Foundation