Tek-Tips is the largest IT community on the Internet today!

Members share and learn making Tek-Tips Forums the best source of peer-reviewed technical information on the Internet!

  • Congratulations IamaSherpa on being selected by the Tek-Tips community for having the most helpful posts in the forums last week. Way to Go!

C++ Builder 6 and NXT++ library 1

Status
Not open for further replies.

floydbloke

Technical User
Aug 12, 2009
5
NZ
I’ll start by pointing out I’m very much a self-taught hobbyist programmer, never having had a need to create a library. I also haven’t used Builder for about two years so please bear with me if my questions seem ignorant or even stupid.
I want to use the NXT++ library found here but I’m struggling to build a .lib file that will work .
Steps taken so far:
• Created new project, and added appropriate folders to project options
• Added comm.cpp and nxt++.cpp to the project
• Edited platform.h to remove reference to MSVC to avoid ‘Unknown Platform’ error
• Temporarily commented out lines containing ‘printf’ to avoid errors
This allows me to create a .lib file. However, when I then try to ‘make’ the little test program, slightly modified to fit with builder,including the .lib file in the Project Manager, it compiles OK but I get a ‘unresolved external’ linker error. (I’m at work and don’t have exact details, I’ll update this post later tonight).
Has anyone here succesfully got the NXT++ library to work with, or perhaps willing to try and get it going for me. Or any other suggestions are much appreciated as well of course.
 
I tried to build the test code with success.

There are 2 thinks you have to do:

1. tell your C++ builder where he can find the header files and the lib files

2. you need to add the conditionel directive __cplusplus.

That's the way I did it working in C++Builder 5:
I downloaded the zip file and into the map
nxtpp. than I unzipped the files into the same folder.

° I opened an form-project
° then I saved the unit.cpp files and the project files in the map nxtpp\nxtpp0-6\Final\bin\win32
° go to Project\options
° open tab Directories\conditionals
° click on the include path [...] bottom
° search for the include map ..\..\include with the browse buttom
° press the add buttom
° again with the browse buttom search for ..\..\include/fantom

Now the same action for the lib-files.
° click on the library path [...] bottom
° search for the source map ..\..\src weth the browse buttom
° press the add button

At the buttom in C++Builder 5 there is a panel 'Condionals'
° again press the [...] type in the text box __cplusplus and press the add buttom.

If you want run code that contain the main function you should open an console project not an form project.

the test file have an main function... but I wish to run it in windows

I placed a Memo on the form and a buttom and copy-pasted the code between main{...} in the onclick-event of the buttom.
Then I replaced code like cout<< "string...." << endl;
with Memo1->Lines->Append("string...");

Be sure you have the right header-files.

So, the reason why you have the unresolved external is that you didn't tell C++Builder where to find the lib files.

You do not need to compile the lib's because they are already compiled.

Please tell me if this was a help for you or why it doesn't work.

Succes Lego-man

 
Thanks for your help. I tried step-by step what you did but still getting "Unresolved external" linker errors for the NXT::Open, NXT::Sensor::SetTouch, functions etc.

A few more points/queries
* Did you get a 'Unknown Platform" error like I did, I got around it by deleting all references to MSVC in platform.h
* I put "#include NXT++.h" in Unit1.h - is this correct?
* The conditional directive _cplusplus is it one "_" or two "__" in fron of cplusplus
* You say to add the ../../src folder to the library path, I can't quite understand why, it has NXT++.cpp and comm.cpp in it but no lib files,
* you also mention the lib has already been compiled, is this the lib file in the target folder, I added it to the project but got a 'invalid OMP record' error.
* if I convert the fantom.lib using coff2omf and add that to the project I'm back to my linker error.
* Do I need to use any 'using namespace" statements?
 
Oops "invalid OMP record" should say "invalid OMF record"

(not edit post feature on this message board??)
 
(not edit post feature on this message board??)
There is if you preview your post first.


James P. Cottingham
I'm number 1,229!
I'm number 1,229!
 
I've been trying lots of different options and am now at least getting some consistency in error messages, namely:
"[Linker Error] Unresolved external 'nFANTOM100::iNXT::createNXTIterator(unsigned short, unsigned long, nFANTOM100::tStatus&)' referenced from C:\NXT\NXTPP\BCBTEST\UNIT1.OBJ"
and similar for destroy.
I've gone back to barebones, not using the NXT++ library (but did use some of the code), but using the 'fantom' files of the Lego support website;
Created a simple form app with Unit1.cpp looking like this:
//---------------------------------------------------------------------------

#include <vcl.h>
#include "fantom/iNXT.h"
#include "fantom/iNXTIterator.h"
#include "fantom/tStatus.h"
#pragma hdrstop

#include "Unit1.h"
//---------------------------------------------------------------------------
#pragma package(smart_init)
#pragma resource "*.dfm"
TForm1 *Form1;
nFANTOM100::tStatus status;
nFANTOM100::iNXTIterator* nxtIteratorPtr = NULL;
nFANTOM100::iNXT* nxtPtr = NULL;

//---------------------------------------------------------------------------
__fastcall TForm1::TForm1(TComponent* Owner)
: TForm(Owner)
{
}
//---------------------------------------------------------------------------

bool __fastcall TForm1::NXTOpen(void)
{
// 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 );

// Creating the NXT iterator object could fail, better check status before dereferencing a
// potentially NULL pointer.
if( status.isNotFatal())
{
// Create an NXT object for the first NXT that was found. Note that if a NXT is found
// over BT, the computer and the NXT must be paired before an NXT object can be
// created. This can be done programatically using the iNXT::pairBluetooth method.
nxtPtr = nxtIteratorPtr->getNXT( status );

// Destroy the NXT iterator object which we no longer need
nFANTOM100::iNXT::destroyNXTIterator( nxtIteratorPtr );
}
return status.isNotFatal();
}
void __fastcall TForm1::Button1Click(TObject *Sender)
{
if (NXTOpen())
Label1->Caption="NXT Brick found";
else
Label1->Caption="Brick not found";
}
//---------------------------------------------------------------------------

I think I’ve set all the Project options correctly, it finds all the include files and compiles OK. Unfortunately I receive the same linker error as above.

So, some further questions:
• I did get the ‘Unknown Platform’ error, but got around that by removing MSVC reference from platform.h. Should I or should I not have done this?
• Do I need to add the fantom.lib file to my project, I’ve tried with and without, and did use the COFF2OMF to convert it. Incidentally, including it unconverted returns the linker error mentioned in my earlier post
• Do I need the conditional directive __CPLUSPLUS (is it case-sensitive)? What does this do?
• The help file says I may not have linked in the emulation library. Do I need this and if so, how do I do it?
 
You are correct.
Following my steps gives the problems you mentioned.
I'm sorry for that, and I can't explain why. But my problem is once build I can not run it.

Concern the Platform' error, when you got this error replace_MSV_VER with _ _BORLANDC_ _ (without spaces)
in the corresponding header files. I think to remember me that I did this twice.

I found code that checked the version of Borland,
So it is better to replace _MSV_VER with _ _BORLANDC_ _ (Without spaces).

Now you don't need to define conditional _ _cplusplus(without spaces).

Did you have Fantom.dll on you computer installed?

At this moment I got an unresolved error for two static declared function. Import Fantom.dll with implib.exe could solve this problem.

 
This I forgot.

If you received the error Comm::... is not a member of comm class

There are 2 comm.h. they have the same name. But in one of them a class is added, thus you will need the other one.

I do not think you must use using namespace. The namespaces are automatically added.

The downloaded files with zip, I found, don't make it easy. It is a little as a chaos and not quit evident to known which file your need to compile or which not.

I'm sure you will find a solution, even without help. But I do enjoy this, trying to found an solution. I hope it will help a little

I added the map with fantom.lib to the search for maps to an lib. Now I known now that fantom.lib is necessary.



 
• I did get the 'Unknown Platform' error, but got around that by removing MSVC reference from platform.h. Should I or should I not have done this?

It depends: It is my understanding that
#define nFANTOM100_kExport __declspec(dllexport)
#define nFANTOM100_kExport __declspec(dllimport)
must be defined. They are necessary for a successfully build.
Without those declaration you may receive an unresolved ... error. They are many ways to solve this problem. If you replace _MSV_VER with _ _BORLANDC_ _ (Without spaces). It should work. I found code that checked the version of Borland. The version must be bigger than 5.x.

[Linker Error] Unresolved external 'nFANTOM100::iNXT::createNXTIterator(unsigned short, unsigned long, nFANTOM100::tStatus&)' referenced from C:\NXT\NXTPP\BCBTEST\UNIT1.OBJ"
and similar for destroy.

This is also what I got as error.

It is my understanding that you supposed to build an TNX++.lib (This one could course the Unresolved external... error)

It is as they did it on purpose, because almost all the conflicts of MSVC and Borland are exploited.

But this shouldn't a big problem. It is my understanding if you add comm.cpp and the NXT++.cpp into your project this should solve the problem. This is as using the NXT++.lib. The difference is you must do this each time, for each new project.

I've succeeded to compile and build an NXT.lib instead of NXT++.lib because Borland C++Builder gives the error not a valid identifier. But also this is not a great problem, because you can manual change the name after you build the lib. So I did.

The question about the emulation library concern creating DLL-files. This is something I could try. To avoid this you must disable runtime libraries. Open an dll project and at the end of the dialog you must uncheck linking with rtl.

I will try this, first.

 
I'am back. Because I wrote some errors.
emulation library concern also for building lib.

After opening an lib project, open the view/properties and click on the tab TLib.

At the end you have the panel rtl option. Disable it.

And I remember me that I have tried it. Something you always should when it won't work...

Once I have create the lib file, the easiest way to use the lib, is add it to the vcl project.

When I build the project I got the same error as you.

I also used coff2omf: coff2omf -q -v "fantom.lib" "fantom.txt" so I can see which functions are exported. I found: follow an extract of fantom.txt

Internal name Imported name

------------- -------------
_nFANTOM100_createNXT FANTOM100_createNXT
_nFANTOM100_createNXTIterator FANTOM100_createNXTIterator
_nFANTOM100_destroyNXT FANTOM100_destroyNXT
_nFANTOM100_destroyNXTIterator FANTOM100_destroyNXTIterator
_nFANTOM100_iFileIterator_advanceFANTOM100_iFileIterator_advance
_nFANTOM100_iFileIterator_getFilFANTOM100_iFileIterator_getFile
_nFANTOM100_iFileIterator_getNameFANTOM100_iFileIterator_getName
_nFANTOM100_iFileIterator_getSizeFANTOM100_iFileIterator_getSize
_nFANTOM100_iFile_close FANTOM100_iFile_close

etc

The two functions are in this file:_nFANTOM100_createNXTIterator
and
_nFANTOM100_destroyNXTIterator

coff2omf is only a help tool. It doesn't work always. This is especially true when the functions are declared static, as is in this case. You can checked it in the header files.

Fantom.lib is an imported type library. It is crated I guess from Fantom.dll.

I don't have this file and I couldn't find it on the internet.

Finally I tried to write a def file as follow:
follow an extraction of the own written def file:
(hmmm I lost it, probably by trying ...) but it goes like this:

EXPORTS
FANTOM100_createNXT =_nFANTOM100_createNXT
FANTOM100_createNXTIterator =_nFANTOM100_createNXTIterator
FANTOM100_destroyNXT =_nFANTOM100_destroyNXT
FANTOM100_destroyNXTIterator =_nFANTOM100_destroyNXTIterator

then import it and then rebuild the project
but without success.

If you have fantom.dll. The best think you can do is import it.

With Borland C++Builder 5.0 you can do this with:
Project/import type lib.
It is here that you also need to unchecked runtime libraries. AndiIt is here that you can do this when the dialog appears.

I must recognise: I'm check mat. Not the first time and surely not the last time.





 
Many thanks luckieluc. The errors you are getting are at least similar to mine, so there is some consistency. I do have fantom.dll, it's part of the driver package that was installed with the Lego software that comes with the NXT.

I will keep trying and let you know how I get on.

In the meantime I have found another 'library', actually, it's more of a 'wrapper' that allows me to send direct commands to the NXT from C++ Builder, via the Bluetooth com port, which is what I initially set out to do.
 
Status
Not open for further replies.

Part and Inventory Search

Sponsor

Back
Top