Re: Changing an argument ... in C++

3 views
Skip to first unread message

Mark

unread,
Sep 8, 2015, 4:36:46 AM9/8/15
to eiffel_...@yahoogroups.com






--- In eiffel_...@yahoogroups.com, "Jimmy Johnson" <boxer41a@...> wrote:
>
>
> If I have a C++ function such as:
>
> c_get_nxt (obj: POINTER; a_status: POINTER): POINTER
> -- Call the cpp method to "create an NXT object for
> -- the NXT referenced by this iterator."
> -- virtual iNXT * getNXT (tStatus &status)=0
>
> the status object is returned to indicate if the operation succeeded.

>
> Can I tell from the C++ signature that the status object is the same that was passed in? That is, can the c call have created a new status object or does the & sign prevent a change?

No the C call cannot replace the status object with another object of type tStatus. Reference types may be thought of as constant pointers.

>
> In C if the signature was (... tStatus *status) would it make a difference?

No. You would have to use the "tStatus**" construction to allow the object to be replaced.

That said, using "tStatus*" in C++ is an idiom for saying that getNXT is obliged to handle an uninitialised status before using it. It is like the concept of "detachable" in Eiffel.

>
> If so, how do you handle this in Eiffel? The pointer "a_status" cannot be assigned to in the C code can it?

The object referenced by a_status can be changed in the C code but not replaced. Intriguingly this means that the following is valid:

tStatus another_status; // construct another status object
// ... do some initialisation of another_status
status = another_status;

because this does not mean: "replace status". It means: "set the instance data of status to the values in another_status".

>
> How do I get both the result and the status from an external call?

Good question! According to my understanding of Eiffel parameter passing, you are entitled to call features of a_status but not to replace it. Thus the semantics of C++ and Eiffel are equivalent.

As I see it, there is nothing special to be done.

Mark

>
> jjj
>




------------------------------------

Yahoo! Groups Links

<*> To visit your group on the web, go to:
http://groups.yahoo.com/group/eiffel_software/

<*> Your email settings:
Individual Email | Traditional

<*> To change settings online go to:
http://groups.yahoo.com/group/eiffel_software/join
(Yahoo! ID required)

<*> To change settings via email:
eiffel_soft...@yahoogroups.com
eiffel_softwar...@yahoogroups.com

<*> To unsubscribe from this group, send an email to:
eiffel_softwa...@yahoogroups.com

<*> Your use of Yahoo! Groups is subject to:
http://docs.yahoo.com/info/terms/

Mark

unread,
Sep 8, 2015, 4:39:56 AM9/8/15
to eiffel_...@yahoogroups.com

Hi David and Jimmy

Out of curiosity, I ran legacy.exe (ES v6.5 - see: "http://docs.eiffel.com/book/solutions/c-externals-0" for details) on my guess at some C++ code for tStatus:

class tStatus
{
public: bool status() const;
private: bool myStatus;
};

This results in (with 'is' and 'indexing' deleted) :

class TSTATUS

inherit
MEMORY
redefine
dispose
end

creation
make

feature -- Initialization

make
-- Create Eiffel and C++ objects.
do
object_ptr := cpp_new
end

feature -- Removal

dispose
-- Delete C++ object.
do
cpp_delete (object_ptr)
end

feature

status: BOOLEAN
-- Call C++ counterpart.
do
Result := cpp_status (object_ptr)
end

feature {NONE} -- Externals

cpp_new: POINTER
-- Call default ctor of C++ class.
external
"C++ [new tStatus %"test.cpp%"] ()"
end

cpp_delete (cpp_obj: POINTER)
-- Call C++ destructor on C++ object.
external
"C++ [delete tStatus %"test.cpp%"] ()"
end

cpp_status (cpp_obj: POINTER): BOOLEAN
-- Value of C++ data member.
external
"C++ [tStatus %"test.cpp%"] (): EIF_BOOLEAN"
alias
"status"
end

feature {NONE} -- Implementation

object_ptr: POINTER

end -- class TSTATUS

Encouraged, I ran it on:

class iNXT
{
virtual iNXT* getNXT (tStatus *status); // NOTE use of pointer
};

But this results in nothing helpful!! That said, I wondered if the following would work - excluding the creation/deletion wrapper code:

class INXT

-- same inherit and create clause as TSTATUS

feature -- Initialization

make
-- Create Eiffel and C++ objects.
do
object_ptr := cpp_new
status := create TSTATUS.make
end

feature -- Status report

status: TSTATUS

feature -- Iteration

get: INXT
-- Call getNXT
do
Result := cpp_get (status.object_ptr) -- see NOTE in TSTATUS above
end

-- Same removal code as for TSTATUS

feature {NONE} -- Externals

-- Same cpp_new and cpp_delete code as for TSTATUS

cpp_get (cpp_obj, status_ptr: POINTER)
-- Call C++ getNXT
-- assumes pointer to status as argument
external
"C++ [iNXT %"inxt.h%"] (EIF_POINTER): EIF_POINTER"
alias
"getNXT"
end

-- Same implementation code as TSTATUS

end -- class INXT

My point previously was that the semantics of Eiffel (according to Object Oriented Software Construction p445) and C++ are identical in regard of argument handling with the given reference or pointer signatures, so functions such as "set_status" should, in theory, be unnecessary.

My question to you both is: does the above idea work in your situation(s)?

Kind regards

Mark

Mark

unread,
Sep 8, 2015, 4:40:36 AM9/8/15
to eiffel_...@yahoogroups.com
feature {INXT} -- Implementation - NOTE change in availability from NONE to INXT

Mark

unread,
Sep 8, 2015, 4:40:57 AM9/8/15
to eiffel_...@yahoogroups.com



Hi David and Jimmy

My thought previously was that the semantics of Eiffel (according to Object Oriented Software Construction p445) and C++ are identical in regard of argument handling with the given reference or pointer signatures. This should mean that functions such as David's "set_status" should, in theory, be unnecessary - except when using expanded Eiffel types.

Out of curiosity, I ran legacy.exe (ES v6.5 - see:
http://docs.eiffel.com/book/solutions/c-externals-0 for details) on my guess at some C++ code for tStatus:

class tStatus
{
public: bool status() const;
private: bool myStatus;
};

This results in (with 'is' and 'indexing' deleted):


--- CODE BEGINS
--- CODE ENDS


Encouraged, I ran it on:

class iNXT
{
virtual iNXT* getNXT (tStatus *status); // NOTE use of pointer and no '=0'
};

But this results in nothing helpful!! That said, I wondered if the following would work - excluding the creation/deletion wrapper code, which is identical to that for TSTATUS:

--- CODE BEGINS

class INXT

-- same inherit clause as TSTATUS

creation
make
make_from_object_ptr

feature -- Initialization

make
-- Create Eiffel and C++ objects.
do
make_from_object_ptr (cpp_new)
end

make_from_object_ptr (ptr: POINTER)
-- Create from object pointer
do
create status.make
object_ptr := ptr
end

feature -- Status report

status: TSTATUS

feature -- Iteration

get: INXT
-- Call getNXT to create a new INXT object
do
create Result.make_from_object_ptr (cpp_get (status.object_ptr))
end

-- Same removal code as for TSTATUS

feature {NONE} -- Externals

-- Same cpp_new and cpp_delete code as for TSTATUS

cpp_get (cpp_obj, status_ptr: POINTER): POINTER
-- Call C++ getNXT
-- assumes pointer to status as argument to getNXT
-- assumes getNXT declared in "inxt.h"
-- assumes ownership of returned iNXT is Eiffel's responsibility
external
"C++ [iNXT %"inxt.h%"] (EIF_POINTER): EIF_POINTER"
alias
"getNXT"
end

-- Same implementation code as TSTATUS

end -- class INXT

--- CODE ENDS

Although more Eiffel code than David's version, this passes a pointer to a C++ object of the correct type (tStatus) to the getNXT function.
This object's state will be changed in the C++ function. In the code above, the changes are made available through an appropriate feature of the wrapper for iNXT.

I would have thought that this kind of code construction achieves the desired effect.

Hope this helps

Mark

unread,
Sep 8, 2015, 4:42:06 AM9/8/15
to eiffel_...@yahoogroups.com

Hi Dave and Jimmy!

Sorry - been away for a while! I'm glad Jimmy found a suitable wrapper. FWIW I believe Jimmy's question is as follows:

If you call a function 'test' defined thus:

class X { public: int value; }; // a dummy class for illustration

void test(X* pX)
{
static X x;
x.value = 27;
pX = &x;
}

Will pX be changed?

The answer is that pX is changed in the body of the function 'test' but NOT outside it. Thus if you call "test" as follows:

#include <iostream>

int main(int, char**)
{
X x;
x.value = 314;
X* px(&x);
test(px);
if (px == &x) cout << "unchanged" << endl; else cout << "changed" << endl;
if (px->value == x.value) cout << "value unchanged" << endl; else cout << "value changed to: " << x.value << endl;
return 0;
}

You will find that the output is:

unchanged
value unchanged

So this is NOT the way to return a new tStatus object, created within function getNXT. However if you define "test" as follows:

void test(X* pX)
{
static X x;
x.value = 27;
*pX = x;
}

The internal attributes of "class X" will be changed through a call to X& operator = (const X&), which will mean that the X object passed to the function will now have identical internal state to the X object within the function. This means that in the calling function (main), X::value is changed. To illustrate, the above code for 'main' will output:

unchanged
value changed to: 27

So the EIF_POINTER parameter in Eiffel is indeed NOT an lvalue because assigning a new pointer to it only changes the object within the scope of the called function (test) and not the calling function (main).

At the risk of losing clarity, if you define test as:

void test(X** ppx) // Note: double indirection
{
static X x;
x.value = 27;
*ppX = &x;
}

You will get the following output, if, in "main", you use: test(&px); /* Note the extra '&' (address of) operator*/:

changed
value changed to: 27

I hope this goes some way to making the matter clearer.

David Jenkins

unread,
Sep 8, 2015, 4:46:50 AM9/8/15
to eiffel_...@yahoogroups.com



>>> So, when status is passed into:
> > > virtual iNXT * getNXT (tStatus &status)=0
> > > it is passed as reference and so cannot be changed. (The
attributes of
> > status can and are changed.) Right?
> >
> > No. "tStatus &status" declares "status" as a reference, so it is
passed
> > by reference and can be changed. According to dear old Prof. Gray (I
> > hope he's still with us), "Declarations of reference variables,
using &,
> > are very similar to declarations of pointers, using *." So "status"
can,
> > and probably does, change. If it were not subject to change it would
> > have been declared "const".
> >
>
> I'm not sure we are talking about the same thing. I realize an
object's attributes can change. So...is &status an Lvalue?

Yes, it's an l-value; it's also a reference (pointer). Here is an
example from Gray:

void swap1(int& a, int& b)
// swap contents of "a" and "b"
{
int temp;
temp = b;
b = a;
a = temp;
}

This is equivalent to:

void swap2(int* a, int* b)
// swap contents of "a" and "b"
{
int temp;
temp = *b;
*b = *a;
*a = temp;
}

BTW, this is also legal (compiles without error and runs):

void swap3(int a, int b)
// swap contents of "a" and "b"
{
int temp;
temp = b;
b = a;
a = temp;
}

It just doesn't swap "a" and "b", except within the scope of the
function. If you declare

int x = 0;
int y = 1;

and call

swap3(x,y);

on return "x" and "y" will have the same values. But if you leave "x=0"
and "y=1" and call "swap1(x,y), then on return x=1 and y=0.

Perhaps more useful to your immediate problem, suppose you declared the
following:

int* v = new int(0);
int* w = new int(1);

then called

swap1((int&)v, (int&)w));

on return "v" and "w" would be swapped.

>In eiffel parameters are not assignable even though they are passed by
reference (except for basic/expanded types). That is why the
hypothetical example is bothering me; a successful compile of the
hypothetical code involving an assignment to the $a_status parameter
implies that the parameter (the POINTER) *can* change. But POINTER, I
believe would be passed by value (a basic type) and is also not
assignable. ????

Are you writing the implementation of "getNXT", or is it supplied? Sorry
if you haven't made this clear already.

Dave

Jimmy Johnson

unread,
Sep 8, 2015, 4:46:50 AM9/8/15
to eiffel_...@yahoogroups.com

Mark, I too think your example is what I need. I don't think I phrased my question correctly. Now that I have gotten [a little] back into C++, let me try again.

In C and C++ are pointers [and/or references] passed by value or reference?

In this code from the example:

int _VI_FUNCC main( int argc, char** argv )
{
nFANTOM100::tStatus status;
nFANTOM100::iNXTIterator* nxtIteratorPtr = NULL;
nFANTOM100::iNXT* nxtPtr = NULL;
nFANTOM100::iFile* filePtr = NULL;
nFANTOM100::iFileIterator* fileIteratorPtr = NULL;

// Create an NXT iterator object which is used to find all accessible NXT devices.
nxtIteratorPtr = nFANTOM100::iNXT::createNXTIterator(
false /* don't search for NXTs over Bluetooth (only search USB) */,
0 /* timeout for Bluetooth discovery ignored */, status );

...

With my inexperience with C++ and all the pointers I did not realize that status was not a pointer, so I could not tell where it was getting initialized. (Now, I believe the default constructor is called at the declaration.) So, when status is passed into:
virtual iNXT * getNXT (tStatus &status)=0
it is passed as reference and so cannot be changed. (The attributes of status can and are changed.) Right?

Okay, so in C, if I pass in a pointer (hypothetical code):
nxt iNXT;
p* tStatus = NULL;
nxt = iNXT (p);
to:
iNXT* getNXT (tStatus* status) { // note signature difference
// do stuff here
status = getPointerToAStatusFromSomewhere;
return = getNXTPointerFromSomewhere;
}

1. In C, can I assign a value to the status pointer like that?
2. If so, how can you get that value to Eiffel, since the POINTER value of the wrapper is not assignable?
c_get_nxt (POINTER: a_status): POINTER
external
"C++ inline use %"iNXTIterator.h%""
alias
"[
$a_status = getPointerToAStatusFromSomewhere
return (EIF_POINTER) getNXT ($a_status);
]"
end

The above assignment in the c-code to $a_status compiles. But what do I really get? Does the value of the POINTER really change? (I have not tested that; I know, I should.)

So back to the original question: if in the C code we are trying to wrap *can* do an assignment to the parameter, how do we get that second value out of the wrapper?

Jimmy Johnson

unread,
Sep 8, 2015, 4:46:50 AM9/8/15
to eiffel_...@yahoogroups.com



--- In eiffel_...@yahoogroups.com, "David Jenkins" <djenkins31751@...> wrote:
>
>
> Hi Jimmy,
>
> Again, I don't mean to pass myself off as a C++ expert by any means. But
> with my ancient copy of Gray's _Programming with Class_ close by, I
> think I can help a little.
>
> > Mark, I too think your example is what I need.
>
> Me too. Mark's suggestion was much better (simpler, cleaner) than mine.
>
> > In C and C++ are pointers [and/or references] passed by value or
> reference?
>
> In C and C++ all function arguments are passed by value. Except ...
>
> > With my inexperience with C++ and all the pointers I did not realize
> that status was not a pointer, so I could not tell where it was getting
> initialized. (Now, I believe the default constructor is called at the
> declaration.) So, when status is passed into:
> > virtual iNXT * getNXT (tStatus &status)=0
> > it is passed as reference and so cannot be changed. (The attributes of
> status can and are changed.) Right?
>
> No. "tStatus &status" declares "status" as a reference, so it is passed
> by reference and can be changed. According to dear old Prof. Gray (I
> hope he's still with us), "Declarations of reference variables, using &,
> are very similar to declarations of pointers, using *." So "status" can,
> and probably does, change. If it were not subject to change it would
> have been declared "const".
>

I'm not sure we are talking about the same thing. I realize an object's attributes can change. So...is &status an Lvalue? In eiffel parameters are not assignable even though they are passed by reference (except for basic/expanded types). That is why the hypothetical example is bothering me; a successful compile of the hypothetical code involving an assignment to the $a_status parameter implies that the parameter (the POINTER) *can* change. But POINTER, I believe would be passed by value (a basic type) and is also not assignable. ????


>
> > Okay, so in C, if I pass in a pointer (hypothetical code):
> > nxt iNXT;
> > p* tStatus = NULL;
> > nxt = iNXT (p);
> > to:
> > iNXT* getNXT (tStatus* status) { // note signature difference
> > // do stuff here
> > status = getPointerToAStatusFromSomewhere;
> > return = getNXTPointerFromSomewhere;
> > }
> >
> > 1. In C, can I assign a value to the status pointer like that?
> > 2. If so, how can you get that value to Eiffel, since the POINTER
> value of the wrapper is not assignable?
> > c_get_nxt (POINTER: a_status): POINTER
> > external
> > "C++ inline use %"iNXTIterator.h%""
> > alias
> > "[
> > $a_status = getPointerToAStatusFromSomewhere
> > return (EIF_POINTER) getNXT ($a_status);
> > ]"
> > end
> >
> > The above assignment in the c-code to $a_status compiles. But what do
> I really get? Does the value of the POINTER really change? (I have not
> tested that; I know, I should.)
>
> I think you get whatever "getPointerToAStatusFromSomewhere" returns
> assigned to $a_status. I'm surprised this compiles though, I would
> expect C++ compilation errors since "$a_status" is not declared as a C++
> variable in the "alias" part of the feature (I would expect the Eiffel
> parameter "a_status" to be translated by the Eiffel compiler to "arg1"
> and available in the body of the C++ code as such. All the inline
> functions I've written recently work that way.)
>
> > So back to the original question: if in the C code we are trying to
> wrap *can* do an assignment to the parameter, how do we get that second
> value out of the wrapper?
> >
>
> This:
> http://nxtpp.clustur.com/projectdocs/classn_f_a_n_t_o_m100_1_1i_n_x_t_it\
> erator.html#4be284f4a8bfb8e73c5df959e1a773b9
> <http://nxtpp.clustur.com/projectdocs/classn_f_a_n_t_o_m100_1_1i_n_x_t_i\
> terator.html#4be284f4a8bfb8e73c5df959e1a773b9> says that "getNXT" is
> pure virtual. Is that true? You're rolling your own "getNXT", right?
>
> Dave
>
>
>
> [Non-text portions of this message have been removed]

David Jenkins

unread,
Sep 8, 2015, 4:46:50 AM9/8/15
to eiffel_...@yahoogroups.com


Hi Jimmy,

Again, I don't mean to pass myself off as a C++ expert by any means. But
with my ancient copy of Gray's _Programming with Class_ close by, I
think I can help a little.

> Mark, I too think your example is what I need.

Me too. Mark's suggestion was much better (simpler, cleaner) than mine.

> In C and C++ are pointers [and/or references] passed by value or
reference?

In C and C++ all function arguments are passed by value. Except ...

> With my inexperience with C++ and all the pointers I did not realize
that status was not a pointer, so I could not tell where it was getting
initialized. (Now, I believe the default constructor is called at the
declaration.) So, when status is passed into:
> virtual iNXT * getNXT (tStatus &status)=0
> it is passed as reference and so cannot be changed. (The attributes of
status can and are changed.) Right?

No. "tStatus &status" declares "status" as a reference, so it is passed
by reference and can be changed. According to dear old Prof. Gray (I
hope he's still with us), "Declarations of reference variables, using &,
are very similar to declarations of pointers, using *." So "status" can,
and probably does, change. If it were not subject to change it would
have been declared "const".

So, if you followed Mark's suggestion and created an Eiffel TSTATUS
class that wrapper the C++ "tStatus" class; then passed its "object_ptr"
(the pointer to the C++ object created by "new" and saved in the Eiffel
class) to "getNXT" as Mark described, I think that will work. It's worth
a try at least.

> Okay, so in C, if I pass in a pointer (hypothetical code):
> nxt iNXT;
> p* tStatus = NULL;
> nxt = iNXT (p);
> to:
> iNXT* getNXT (tStatus* status) { // note signature difference
> // do stuff here
> status = getPointerToAStatusFromSomewhere;
> return = getNXTPointerFromSomewhere;
> }
>
> 1. In C, can I assign a value to the status pointer like that?
> 2. If so, how can you get that value to Eiffel, since the POINTER
value of the wrapper is not assignable?
> c_get_nxt (POINTER: a_status): POINTER
> external
> "C++ inline use %"iNXTIterator.h%""
> alias
> "[
> $a_status = getPointerToAStatusFromSomewhere
> return (EIF_POINTER) getNXT ($a_status);
> ]"
> end
>
> The above assignment in the c-code to $a_status compiles. But what do
I really get? Does the value of the POINTER really change? (I have not
tested that; I know, I should.)

I think you get whatever "getPointerToAStatusFromSomewhere" returns
assigned to $a_status. I'm surprised this compiles though, I would
expect C++ compilation errors since "$a_status" is not declared as a C++
variable in the "alias" part of the feature (I would expect the Eiffel
parameter "a_status" to be translated by the Eiffel compiler to "arg1"
and available in the body of the C++ code as such. All the inline
functions I've written recently work that way.)

> So back to the original question: if in the C code we are trying to
wrap *can* do an assignment to the parameter, how do we get that second
value out of the wrapper?
>

This:
http://nxtpp.clustur.com/projectdocs/classn_f_a_n_t_o_m100_1_1i_n_x_t_it\
erator.html#4be284f4a8bfb8e73c5df959e1a773b9
<http://nxtpp.clustur.com/projectdocs/classn_f_a_n_t_o_m100_1_1i_n_x_t_i\
terator.html#4be284f4a8bfb8e73c5df959e1a773b9> says that "getNXT" is
pure virtual. Is that true? You're rolling your own "getNXT", right?

Dave



[Non-text portions of this message have been removed]



Jimmy Johnson

unread,
Sep 8, 2015, 4:46:50 AM9/8/15
to eiffel_...@yahoogroups.com


If I have a C++ function such as:

c_get_nxt (obj: POINTER; a_status: POINTER): POINTER
-- Call the cpp method to "create an NXT object for
-- the NXT referenced by this iterator."
-- virtual iNXT * getNXT (tStatus &status)=0

the status object is returned to indicate if the operation succeeded.

Can I tell from the C++ signature that the status object is the same that was passed in? That is, can the c call have created a new status object or does the & sign prevent a change?

In C if the signature was (... tStatus *status) would it make a difference?

If so, how do you handle this in Eiffel? The pointer "a_status" cannot be assigned to in the C code can it?

How do I get both the result and the status from an external call?

jjj

David Jenkins

unread,
Sep 8, 2015, 4:46:50 AM9/8/15
to eiffel_...@yahoogroups.com

Hi Jimmy,

I've been wrestling with similar issues for the past 3 weeks. Three
weeks does not a C/C++ expert make, but here's what I've done:

> In C if the signature was (... tStatus *status) would it make a
difference?

Your "tStatus *status" parameter is an address, so I assume that the
C/C++ function may/probably will change the value of the declared
variable. IOW, if you declared

tStatus status

and then in C called the function like this

result = cpp_get_next(..., &status) /* C function call */

then I'd assume that "status" will change. Sorry if I'm stating the
obvious.

The question then is, what to do about "status"? It gets changed, and
the function also returns a value "result" (some sort of POINTER in your
example). You need to do something meaningful with 2 values returned by
the function, one as a parameter, and one as its return value. This is
common practice in C, but, as I've been reminded recently by Roger and
Helmut (very nicely and thoroughly convincingly), it's not recommended
in Eiffel to change the value of a parameter passed to a function in an
Eiffel feature. (It's probably not a good idea to do it in C either, but
it's seems to be universal.)

So what I've done is to take advantage of the new "inline" syntax, and
write C code in an Eiffel "external" routine that calls an Eiffel
"setter" command for the C parameter that changed. Let's assume, to keep
things simple, that your "status" is a C "int" (and not the more
complicated "tStatus"). In the Eiffel class MY_EIFFEL_WRAPPER you could
create an Eiffel attribute called "status":

status: INTEGER

and a setter routine:

feature {NONE} -- don't allow other objects to change "status"
set_status (s: INTEGER)

You would also need to make "set_status" visible (in the Project
Settings window, select the cluster in which the class appears, open the
"Advanced" element, select the value box of "Visible Classes", and in
the resulting dialog enter both the Eiffel class name and the
"set_status" feature name).

Now, for the Eiffel "external" routine. Add the Current object to the
parameter list of the external routine:

cpp_get_next (obj: MY_EIFFEL_WRAPPER)
external
"C++ inline use <c_header_file.h>"
alias
"[
// C++ code goes here
]"
end

MY_EIFFEL_WRAPPER is the Eiffel class with the "status" and "set_status"
features. You will need a C pointer to the Eiffel function "set_status"
in order to call it. That can be done this way:
// Insert following between the "[ and ]" tokens
in the alias part
// along with other C code
EIF_PROCEDURE ep_ss; // Pointer to Eiffel
function "set_status"
EIF_TYPE_ID tid;
tid = eif_type(arg1); // "arg1" is the
parameter whose type
// is
MY_EIFFEL_WRAPPER
ep_ss = eif_procedure("set_status",tid);
if(ep_ss == NULL) // for debugging only,
unnecessary once it's working
{
cout << "ep_ss not found/visible\n";
return EIF_<sometype>;
}

Now declare C/C++ variables, call the C/C++ function, and return the
"status" to the Eiffel class:

int status; // your case is more complicated
but the principle is the same
get_next (/* possible parameters */, &status);
(ep_ss) (eif_access(arg1),status); // call
"set_status" and pass "status"

In this way the "status" is returned to the Eiffel class and is visible
as an Eiffel attribute. The external function is free to return a result
as well, which may or may not also need to be assigned to an Eiffel
attribute.

I've simplified things--your "tStatus" type is doubtless more
complicated than an "int"--but you get the general idea. This approach
is working great for me, and conforms to the CQS convention.

Real Eiffel/C/C++ experts, please jump in!

David Jenkins

--- In eiffel_...@yahoogroups.com, "Jimmy Johnson" <boxer41a@...>
wrote:
>
>

Jimmy Johnson

unread,
Sep 8, 2015, 4:46:50 AM9/8/15
to eiffel_...@yahoogroups.com



--- In eiffel_...@yahoogroups.com, "David Jenkins" <djenkins31751@...> wrote:
>
>
>
Okay, I see. I'm still not convinces the POINTER paramenter in an Eiffel wrapper is an Lvalue. I might test that some day.

> >In eiffel parameters are not assignable even though they are passed by
> reference (except for basic/expanded types). That is why the
> hypothetical example is bothering me; a successful compile of the
> hypothetical code involving an assignment to the $a_status parameter
> implies that the parameter (the POINTER) *can* change. But POINTER, I
> believe would be passed by value (a basic type) and is also not
> assignable. ????
>
> Are you writing the implementation of "getNXT", or is it supplied? Sorry
> if you haven't made this clear already.
>
> Dave
>

I'm using a supplied version; that was just a contrived example.
I actually found a C++ library that already wrapped fantom, so I wrapped it instead. It appears to be working well enough for me to use as a teaching tool.

Liberty Lover

unread,
4:31 PM (6 hours ago) 4:31 PM
to Eiffel Users

Liberty Lover

unread,
4:37 PM (6 hours ago) 4:37 PM
to eiffel...@googlegroups.com

--
You received this message because you are subscribed to the Google Groups "Eiffel Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to eiffel-users...@googlegroups.com.
To view this discussion visit https://groups.google.com/d/msgid/eiffel-users/4ef97427-3f15-444a-b95b-e4267bd579can%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages