Re: Plea for help with C++ wrappers

6 views
Skip to first unread message

colinlema

unread,
Sep 7, 2015, 4:05:35 PM9/7/15
to eiffel_...@yahoogroups.com

One thing to remember is that :: is doing both namespace resolution and a static method call; it's not a member or feature call on an object. So when it's asking the iNXT 'class' for an iterator, it's really like asking a global function for an iterator, they just happened to tie it to the iNXT class for some reason. I agree that wasn't a good choice of placement on their part.

A member call on an object of the iNXT class would look like:
nxtPtr->method_call();

A static call to a function attached to the iNXT class would look like:
iNXT::static_method_call();

Notice how iNXT isn't an instance, it's the class.

--- In eiffel_...@yahoogroups.com, "Jimmy J. Johnson" <boxer41a@...> wrote:
>
> I am trying to make a wrapper of the Fantom API for the Lego Mindstorms robot and then use the `sendDirectCommand' method to send commands to the NXT. But I am having trouble getting the cpp wrappers to compile. (I flushed my brain cells of C/C++ when ISE released 3.1 for the PC; now I am paying for that.) I hope I am not asking too much, but I don't know where else to turn.
>
> Thanks,
>
> Jimmy J. Johnson
>
>
> Below is the sendDirectCommand method for reference:
>
> virtual ViUInt32 sendDirectCommand( ViBoolean requireResponse, const ViByte commandBufferPtr[], ViUInt32 commandBufferSizeInBytes, ViPBuf responseBufferPtr, ViUInt32 responseBufferSizeInBytes, tStatus& status ) = 0;
>
> I can follow an example wrapper if someone could provide examples for creating an iNXT, iNXTIterator, and a tStatus object. In the example program they create an iNXTIterator and then use that to get an iNXT object. But the createNXTIterator feature is in iNXT class. It seems circular to me; I need an iNXT to make the iterator but I need an iterator to make the nxt? Here is [most of] the first part of the example program:
>
> int _VI_FUNCC main( int argc, char** argv )
> {
> nFANTOM100::tStatus status;
> nFANTOM100::iNXTIterator* nxtIteratorPtr = NULL;
> nFANTOM100::iNXT* nxtPtr = NULL;
> // Create an NXT iterator object to find all accessible NXT devices.
> nxtIteratorPtr = nFANTOM100::iNXT::createNXTIterator(
> false /* search for NXTs using USB only */,
> 0 /* timeout for Bluetooth discovery ignored */, status );
> if( status.isNotFatal())
> { nxtPtr = nxtIteratorPtr->getNXT( status );
> // Destroy the NXT iterator object which we no longer need
> nFANTOM100::iNXT::destroyNXTIterator( nxtIteratorPtr );
> }
>
>
>
> Here is the feature from iNXT.h:
>
> nFANTOM100_kExport static iNXTIterator* _VI_FUNCC createNXTIterator(
> ViBoolean searchBluetooth, ViUInt32 bluetoothSearchTimeoutInSeconds,
> tStatus& status );
>
>
> from iNXTIterator.h:
>
> virtual iNXT* getNXT( tStatus& status ) = 0;
>
>
> and from tStatus.h:
>
> namespace nFANTOM100
> {
> // classes...
> const ViInt32 kStatusOffset = -142000; // 0xFFFDD550
> const ViStatus kStatusSuccess = VI_SUCCESS;
>
> /*!
> \brief Enumeration of Fantom-specific status codes. NI-VISA status codes may also be
> returned. These are documented in the NI-VISA Programmer Reference Manual which is
> available from <http://ni.com/>.
> */
> enum tFANTOMStatus
> {
> kStatusFirst = (kStatusOffset + 0),
>
> //! Error: Bluetooth pairing operation failed.
> //! Warning: You have already paired with that Bluetooth device.
> kStatusPairingFailed = (kStatusOffset + -5), // 0x54B
>
> //! Error: Bluetooth search failed.
> kStatusBluetoothSearchFailed = (kStatusOffset + -6), // 0x54A
>
> -- {snip} a whole bunch of other enumerartions.
>
> kStatusLast = (kStatusOffset + -999)
> };
>
> /*!
> \brief Class that contains a status code and the file name and line number where that
> status code was generated.
> */
> class tStatus
> {
> public:
>
> // methods
>
> //! constructor
> /*!
> Creates a tStatus object intialized to success.
>
> \post The status code is set to VI_SUCCESS.
> */
> inline tStatus( void ) :
> _code( VI_SUCCESS ),
> _lineNumber( 0 )
> {
> _fileName[0] = '\0';
> }
>
> -- {snip} other features removed.
>
> private:
> // declared private to prevent assignment
> tStatus& operator=(const tStatus& rhs);
> enum
> {
> kMaxFileNameLength = 101
> };
> ViStatus _code;
> ViChar _fileName[ kMaxFileNameLength ];
> ViUInt32 _lineNumber;
> };
>




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

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:
mailto:eiffel_soft...@yahoogroups.com
mailto: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/

colinlema

unread,
Sep 7, 2015, 4:05:55 PM9/7/15
to eiffel_...@yahoogroups.com

Strictly speaking you don't have to follow their abstractions at all. It would be a design decision, do you want your Eiffel code to look exactly like their code, or do you want to make better abstractions.

The pattern I've seen many people used and I find very useful, is to make a couple Eiffel classes that simply wrap the C++ functions. On top of these wrapper classes you can make some better abstractions. Maybe one Eiffel class per C++ class or one Eiffel class per C++ file, depending on how the C++ is divided up.

--- In eiffel_...@yahoogroups.com, "Jimmy J. Johnson" <boxer41a@...> wrote:
>
> I think I see. So when I make a wrapper for that "feature" I can put it in any class?

Jimmy J. Johnson

unread,
Sep 7, 2015, 4:07:16 PM9/7/15
to eiffel_...@yahoogroups.com

Jimmy J. Johnson

unread,
Sep 7, 2015, 4:07:16 PM9/7/15
to eiffel_...@yahoogroups.com

I think I see. So when I make a wrapper for that "feature" I can put it in any class?


--- In eiffel_...@yahoogroups.com, "colinlema" <clemahieu@...> wrote:
>
> One thing to remember is that :: is doing both namespace resolution and a static method call; it's not a member or feature call on an object. So when it's asking the iNXT 'class' for an iterator, it's really like asking a global function for an iterator, they just happened to tie it to the iNXT class for some reason. I agree that wasn't a good choice of placement on their part.
>
> A member call on an object of the iNXT class would look like:
> nxtPtr->method_call();
>
> A static call to a function attached to the iNXT class would look like:
> iNXT::static_method_call();
>
> Notice how iNXT isn't an instance, it's the class.
>

Jimmy J. Johnson

unread,
Sep 7, 2015, 4:07:16 PM9/7/15
to eiffel_...@yahoogroups.com

No, I don't want to follow a bad design if I don't have to. I also don't need to wrap every routine. I just can't get the c++ syntax correct.

Is the code below the correct approach?

If so, can someone tell me the syntax for feature `c_create'?

Thanks,

Jimmy J. Johnson



class
NXT_ITERATOR
inherit
ANY
redefine
default_create
end
create
default_create
feature {NONE} -- Initialization
default_create is
-- Initialize an iterator
do
cpp_object := c_create
end
feature {NONE} -- Implementation
c_create: POINTER is
-- Call the cpp constructor
external
"C++ inline use %"iNXTIterator.h%""
alias
"[
iNXTIterator *it;
return new it;
]"
end
cpp_object: POINTER
-- cpp handle to the iterator
end





--- In eiffel_...@yahoogroups.com, "colinlema" <clemahieu@...> wrote:
>
> Strictly speaking you don't have to follow their abstractions at all. It would be a design decision, do you want your Eiffel code to look exactly like their code, or do you want to make better abstractions.
>
> The pattern I've seen many people used and I find very useful, is to make a couple Eiffel classes that simply wrap the C++ functions. On top of these wrapper classes you can make some better abstractions. Maybe one Eiffel class per C++ class or one Eiffel class per C++ file, depending on how the C++ is divided up.
>

Liberty Lover

unread,
Dec 26, 2025, 4:31:40 PM (10 hours ago) Dec 26
to Eiffel Users

Liberty Lover

unread,
Dec 26, 2025, 4:37:40 PM (9 hours ago) Dec 26
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/17a6f401-621b-472f-a9cf-d1066d28120an%40googlegroups.com.
Reply all
Reply to author
Forward
0 new messages