I am trying some code from DaCarSoft from the spanish forum http://www.glbasic.com/forum/index.php?topic=6463.msg79425#msg79425 (http://www.glbasic.com/forum/index.php?topic=6463.msg79425#msg79425)
I Created a GLB project and included iOSKeyBoadTest.gbas and the iOSKeyBoadTest.mm
when I compile I get the following errors from the linker:
Code: GLBasic [Select]
linking:
gpc_temp0.o:gpc_temp0.cpp:(.text+0x1f6): undefined reference to `_iOSMessageBox'
gpc_temp0.o:gpc_temp0.cpp:(.text+0x59a): undefined reference to `_GetiOSMessageBoxValues'
gpc_temp0.o:gpc_temp0.cpp:(.text+0x6ed): undefined reference to `_iOSMessageBox'
gpc_temp0.o:gpc_temp0.cpp:(.text+0x8ef): undefined reference to `_GetiOSMessageBoxValues'
*** FATAL ERROR - Please post this output in the forum
The iOSKeyBoadTest.gbas includes this code:
IMPORT "C" void iOSMessageBox(const char*,const char*, const char*, const char*)
IMPORT "C" const char* GetiOSMessageBoxValues()
GLOBAL MENSAJE$
// El nuevo símbolo de separación para los parámetros a pasar a la función es la "tubería", antes era $, en mi código anterior...
iOSMessageBox("Título","Mensaje" + CHR$(0xD) + CHR$(0xD) + CHR$(0xD) + CHR$(0xD), "Esto es una prueba ü Ñ |:P", "Aceptar|Cancelar")
LOCAL InstanteComienzo% = GETTIMERALL()
MENSAJE$ = ""
WHILE MENSAJE$ = ""
SLEEP 500
WHILE ABS(GETTIMERALL() - InstanteComienzo%) < 500
HIBERNATE
WEND
MENSAJE$ = GetiOSMessageBoxValues()
WEND
PRINT MENSAJE$, 100, 100
SHOWSCREEN
HIBERNATE
MOUSEWAIT
iOSMessageBox("Título","Mensaje" + CHR$(0xD) + CHR$(0xD), "Esto es otra prueba", "Aceptar|Cancelar")
InstanteComienzo% = GETTIMERALL()
MENSAJE$ = ""
WHILE MENSAJE$ = ""
SLEEP 500
WHILE ABS(GETTIMERALL() - InstanteComienzo%) < 500
HIBERNATE
WEND
MENSAJE$ = GetiOSMessageBoxValues()
WEND
PRINT MENSAJE$, 100, 100
SHOWSCREEN
HIBERNATE
MOUSEWAIT
and the iOSKeyBoadTest.mm this:
#if defined (TARGET_OS_IPHONE)
// UIALERT
//#import <UIKit/UIAlert.h> // No es necesario duplicar la importación hecha con anterioridad
@interface GLBasicMessageBoxer: NSObject <UIAlertViewDelegate>
{
// Declaración de los punteros para los elementos comunes
UITextField* txtObject;
NSMutableArray* resObjects;
NSString* resValues;
NSString* pTitle,* pMessage,* pLabels,* pButtons;
}
@end
@implementation GLBasicMessageBoxer
// Llamada necesaria para llamar al código que muestra el Alert en el proceso principal
- (void)showAlertCaller:(NSString*)cTitle andMessage:(NSString*)cMessage andLabels:(NSString*)cLabels andButtons:(NSString*)cButtons
{
// Introducción de los valores pasados como parámetro punteros accesibles por "showAlert"
pTitle = [[NSString alloc] initWithString:cTitle];
pMessage = [[NSString alloc] initWithString:cMessage];
pLabels = [[NSString alloc] initWithString:cLabels];
pButtons = [[NSString alloc] initWithString:cButtons];
// Llamada a "showAlert" enviándola al proceso principal
[self performSelectorOnMainThread:@selector(showAlert) withObject:nil waitUntilDone:NO];
}
- (void)showAlert
{
// Creación de la vista para el Alert
UIAlertView* alert = [[UIAlertView alloc] init];
alert.title = pTitle;
alert.message = pMessage;
alert.delegate = self;
// Anulación de la asignación de la función de cancelar al botón con índice 0
alert.cancelButtonIndex = -1;
// Creación de la matriz de botones introduciendo valores según los parámetros pasados separados por "|"
NSArray* aButtons = [pButtons componentsSeparatedByString:@"|"];
// Creación de cada botón a partir de cada valor de la matriz
for (NSString* iObject in aButtons){
[alert addButtonWithTitle:iObject];
}
// Creación de la matriz de controles de texto introduciendo valores según los parámetros pasados separados por "|"
if (pLabels != @"") {
double iPos = 70.0;
NSArray* aLabels = [pLabels componentsSeparatedByString:@"|"];
resObjects = [[NSMutableArray alloc] init];
// Creación de cada control de texto con las propiedades adecuadas asegurando que no devuelve un valor "(null)" mediante .text = @""
for (NSString* iObject in aLabels){
txtObject = [[UITextField alloc] init];
txtObject.frame = CGRectMake(12.0, iPos, 260.0, 25.0);
txtObject.text = @"";
txtObject.placeholder = iObject;
txtObject.backgroundColor = [UIColor whiteColor];
txtObject.clearButtonMode = UITextFieldViewModeWhileEditing;
txtObject.keyboardType = UIKeyboardTypeAlphabet;
txtObject.keyboardAppearance = UIKeyboardAppearanceAlert;
txtObject.autocapitalizationType = UITextAutocapitalizationTypeNone;
txtObject.autocorrectionType = UITextAutocorrectionTypeNo;
txtObject.borderStyle = UITextBorderStyleLine;
// Colocación del foco si es el primer control creado para introducción de texto
if ([aLabels indexOfObject:iObject] == 0) {
[txtObject becomeFirstResponder];
// El teclado aparece automáticamente al colocar el foco en un control de texto
}
// Aumentar el valor de la variable que controla la coordenada de posición del "top" de cada control de texto
iPos = iPos + 30.0;
// Asociación de cada control a la matriz mutable
[resObjects addObject:txtObject];
// XCode soporta añadir controles de texto directamente a un Alert pero Apple no permite su uso directo al no estar documentado
// Para poder imitar el comportamiento pueden agregarse "subvistas" al Alert e introducir los controles necesarios en ellas
[alert addSubview:txtObject];
[txtObject release];
txtObject = nil;
}
}
[alert show];
[alert release];
}
// Recogida del botón pulsado en la memoria mediante la propiedad "delegate" (= self) asignada en "showAlert"
- (void)alertView:(UIAlertView*)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
resValues = [[NSString alloc] initWithFormat:@"%d", buttonIndex];
}
// Código que obtiene y trata los valores para construir el resultado mediante valores separados por "|"
- (void)getValues
{
// Agregado a la cadena del botón pulsado de los valores de cada control de texto en el Alert
for (UITextField* iObject in resObjects){
// Insertar el texto recogido del control en un NSMutableString
NSMutableString* tmpObjectValue = [[NSMutableString alloc] initWithString:iObject.text];
// Reemplazar el caracter usado en el código como separador de valores si el usuario lo ha introducido en los controles
[tmpObjectValue replaceOccurrencesOfString:@"|" withString:@"!" options:0 range:NSMakeRange(0, [tmpObjectValue length])];
// Agregar el valor obtenido al contenido anterior de la memoria
resValues = [resValues stringByAppendingFormat:@"|%@", tmpObjectValue];
// Liberar la memoria
[tmpObjectValue release];
tmpObjectValue = nil;
}
// Creación de otro puntero "NSData" temporal para albergar los valores obtenidos transformados para evitar errores por "encodings"
NSData* tmpValuesEncoded = [[NSData alloc] init];
// Conversión de la cadena obtenida a un "encoding" Windows Latin obviando los caracteres no reconocidos mediante "allowLossyConversion"
tmpValuesEncoded = [resValues dataUsingEncoding:NSWindowsCP1252StringEncoding allowLossyConversion:YES];
// Reintroducción de la cadena final convertida al "encoding" adecuado para que pueda devolverse desde "getValuesCaller"
resValues = [[NSString alloc] initWithData:tmpValuesEncoded encoding:NSWindowsCP1252StringEncoding];
// Liberar la memoria
tmpValuesEncoded = nil;
}
// Obtención de los valores del botón pulsado y texto introducido en los controles recuperando los valores desde el proceso principal
- (const char*)getValuesCaller
{
// Comprobación de si se ha pulsado un botón del Alert
if (resValues != nil){
// Llamada a "getValues" en el proceso principal
[self performSelectorOnMainThread:@selector(getValues) withObject:nil waitUntilDone:YES];
// Devolvemos el valor de la cadena preparada desde "getValues"
return [resValues cStringUsingEncoding:NSWindowsCP1252StringEncoding];
// Liberar la memoria
[resObjects release];
resObjects = nil;
[resValues release];
resValues = nil;
[pTitle release];
pTitle = nil;
[pMessage release];
pMessage = nil;
[pLabels release];
pLabels = nil;
[pButtons release];
pButtons = nil;
[self release];
[super dealloc];
}
else
{
// Si no se ha pulsado ningún botón se devuelve una cadena vacía
return "";
}
}
@end
// Creación del puntero para las funciones contenidas en "GLBasicMessageBoxer" a usar cada vez que se requiera un Alert
GLBasicMessageBoxer* newAlert;
// Creación de función "externalizada" a usar desde GLBasic (los parámetros "labels" y "buttons" pueden contener varios valores separados con "$")
extern "C" void iOSMessageBox(const char* cTitle, const char* cMessage, const char* cLabels, const char* cButtons)
{
newAlert = [[GLBasicMessageBoxer alloc] init];
// Conversión de tipos "C" a "NSString" al recuperar los parámetros enviados desde GLBasic y lanzado del Alert
[newAlert showAlertCaller:[NSString stringWithCString:cTitle encoding:NSASCIIStringEncoding] andMessage:[NSString stringWithCString:cMessage encoding:NSASCIIStringEncoding] andLabels:[NSString stringWithCString:cLabels encoding:NSASCIIStringEncoding] andButtons:[NSString stringWithCString:cButtons encoding:NSASCIIStringEncoding]];
}
// Creación de la función "externalizada" a usar desde GLBasic (los parámetros devueltos son valores separados con "$")
extern "C" const char* GetiOSMessageBoxValues()
{
// Se recuperan en primer lugar el índice de botón pulsado y a continuación los textos introducidos en los controles generados
return [newAlert getValuesCaller];
}
// FIN UIALERT
#endif
Are you adding the nm file to the XCode project ?
Yes I it is in the XCode project directory, but the compilation error is happening in GLB!
Have you selected multiplatform build for iphone?
You'll get those linker errors if you build for windows. I think what happens is that if you build for iphone the linker doesn't try to resolve the external functions. The library the compiler builds will be linked in xcode to the mm file. But if you don't build for iphone then the linker tries to resolve the external functions and won't find them because it doesn't link to the mm file.
Just my 2 cents.
Yes I did.
Like I said the error I reported is from GLBasic and I tried in V10.xxx and V11.xxx same result.
If I ignore the GLBasic error and execute my code in Xcode Liinker complains about undefined symbols as you can see below.
Undefined symbols for architecture armv7:
"_iOSMessageBox", referenced from:
__GLBASIC__::__MainGameSub_() in libPROGRAM.a(gpc_temp0.o)
"_GetiOSMessageBoxValues", referenced from:
__GLBASIC__::__MainGameSub_() in libPROGRAM.a(gpc_temp0.o)
ld: symbol(s) not found for architecture armv7
clang: error: linker command failed with exit code 1 (use -v to see invocation)
I'm using v 10.283.
I started a new project. Copied and pasted the contents of your gbas file. I didn't do anything with the code in your mm file - left it out completely.
I chose 'build' (f8) from the menu and got the following linker errors:
gpc_temp0.o:gpc_temp0.cpp:(.text+0x1da): undefined reference to `_iOSMessageBox'
gpc_temp0.o:gpc_temp0.cpp:(.text+0x3e9): undefined reference to `_GetiOSMessageBoxValues'
gpc_temp0.o:gpc_temp0.cpp:(.text+0x6ac): undefined reference to `_iOSMessageBox'
gpc_temp0.o:gpc_temp0.cpp:(.text+0x8b0): undefined reference to `_GetiOSMessageBoxValues'
I then chose 'build multiplatform' (shift f8), chose iPhone pressed ok and got no link errors. That's why I thought you may not have been building for iPhone.
I think the error means that your object file (gpc_temp0.o) makes reference to functions that the linker can't find.
Edit: I'm just not sure why there is an attempt to link your object files when building for iPhone because they should just be aggregated into a library (libPROGRAM.a) for xcode to link against.
Can you step out what you're doing?
marovada,
Thanks again, I agree with your comment , the references should be in the libPROGRAM.a, the GLBasic compeller/Linker should be doing that.
Something is missing in the gbas file.
I will keep researching the forum and the Xcode tutorials.
What do you mean by: Can you step out what you're doing?
If I understood correctly, I am trying to open the iOS native keyboard, and receive key strokes in the GBL program.
My goal is to learn how to pass and receive data from iOS into GLB and then implement iAds
Hi aroldo,
I meant to ask how you set up the project and then compiled it in GLBasic ie the steps you took to create a new project, add the files, choose compile option etc.
I'm asking this because I got your code to work by copying the code from your gbas file (in your first post) into a new project. It works perfectly for me when I build for iPhone so there is nothing missing in the gbas file.
It's odd that it didn't work for you because I'm using the same code. I only got the errors you've been getting when I build for windows, not for iPhone.
Edit: when you build for windows the linker tries to resolve the missing functions because it's creating an executable file. When you build for iPhone, you're just building a library of object files so there is no need to resolve the missing functions. They will get picked up by xcode when you build the mm file and link against the library to get the iphone executable ('app'). So it just sounds to me like there's some step you might be taking in setting up your project that's causing the problem.
Can you make the project available ?
Here it is:
https://www.dropbox.com/s/opj6drvf3yxzwau/iosKeyboardTest.zip (https://www.dropbox.com/s/opj6drvf3yxzwau/iosKeyboardTest.zip)
It compiles fine here too - it should be fine with XCode (as long as the mm file is included too).
MrTAToad and marovada,
Thank you.
I moved the .mm file to the Class folder in the XCode project and now I have different errors in the .mm file that I have to fix.
See attachments.
I haven't compiled for iPhone for a very long time, but I think you need to change the processor selection to ARM6 or something...
It builds fine for me. Here is my project:
https://www.dropbox.com/s/cz0i8npet59ngxf/XCode.zip (https://www.dropbox.com/s/cz0i8npet59ngxf/XCode.zip)
What version of xcode do you have?
As I said here:
http://www.glbasic.com/forum/index.php?topic=8544.msg79309#msg79309 (http://www.glbasic.com/forum/index.php?topic=8544.msg79309#msg79309)
http://www.glbasic.com/forum/index.php?topic=8544.msg78455#msg78455 (http://www.glbasic.com/forum/index.php?topic=8544.msg78455#msg78455)
http://www.glbasic.com/forum/index.php?topic=6463.msg79429#msg79429 (http://www.glbasic.com/forum/index.php?topic=6463.msg79429#msg79429) (sorry, it is in spanish)
There are problems with GLBasic and last version of Xcode. I fixed it (making my own Xcode project), but I suppose Gernot/Hello Kitty knows it (because I usually haven't replies to my comments from anyone, feeling that they are not understood or ignored) and I suppose that these problems will be solved in future versions of the "so called" beta 11.
Hope so!
Yes, me too. I mean - I did a fresh clean build of one of my apps and it was working. Can someone confirm that the V11 beta works with clean projects and the latest XCode?
I tested it and with a fresh new project, all appears to work fine until you modifies the Xcode project, for example by adding wrappers... Then Xcode won't compile, throwing ARM7 errors like in the screenshots posted by Aroldo.
Also this error is related with the fact that each time you compiles from GLBasic, the Xcode project is overwritten, losing all the changes made to it.
My solution was to make my own Xcode project from zero, including manually all the frameworks and ".a" libraries erasing the files of the Xcode project that GLBasic uses as source to be copied to the project folder each time you compiles.
iPhone 5 screen resolution is also unsupported. I added the iPhone 5 resolution in the GLBasic's project settings but it only uses the iPhone 4 resolution, I suppose that the dimensions for the internal OpenGL window/view are not correctly adjusted at the load of the application from Xcode.
As I wrote in other posts also, the rotation of the screen has been changed in iOS 6, and I suppose that it will work in the same way under iOS 7, this change affects the way in which appears the bottom multitasking bar in iPad. This problem can be solved with wrappers, but may be that the best way to solve it is including the needed code to the internal GLBasic's Xcode part.
I have iPad 4, iPhone 5 as devices for testing, a MacBook Pro 2011 as development laptop with Windows XP as virtual machine. My Xcode version is 4.6.2 and my GLBasic version is Beta 11.414.
EDIT: I found the error in the GLBasic/Xcode's project that is avoiding wrappers to run. The project it is not precompiling the "Prefix Header", the file with the ".pch" extension that old versions of GLBasic have, also, the file is not present in the GLBasic's folders.
Obviously the other errors that I said before are still there.
EDIT 2: Again, I noticed that the iCade "grey/shadows line" at the bottom of the GLBasic's screen appears (again) when you compiles using this last Beta. I just tested the same project and code without problems compiling it with my old Beta, the one that I used for testing purposes in the past, when I helped Gernot to fix the iCade problems.
GERNOT: If you like, you can PM me or send me an email with the same Xcode's files that you sent me in the past, if you need help.
I think the errors about GLB symbols "undefined in armv7" is because the GLB libraries are compiled for armv6, and the last XCode SDK 6.x ignores the code compiled for this cpu (but it's compatible with armv7). In other XCode versions you can add armv6 compatibility, but this time they don't want this.
I solved it HardyX...
It is a problem related to the "prefix file" and Xcode project settings... Like I said before :P
Thank you all for your help.
Can someone post how the "prefix file" and Xcode project settings should be?
You can copy the .pch file from an old version of GLBasic or other old GLBasic project to the Xcode project folder.
After, you have to add the configuration to Xcode, like in this screenshot.