pascal icloud - Código de enlace Delphi XE6 C en iOS




itunes iphone (2)

Creé una aplicación en Android usando Delphi XE6 que requiere código C. Sin embargo, en iOS no puedo hacer que funcione. Sospecho que el problema está relacionado con el estado del brazo / pulgar, pero no estoy seguro. No hay ningún problema en ninguno de los sistemas para llamar al código C de Pascal. Pero si el código C vuelve a llamar a un procedimiento Pascal, iOS genera una "bad system call (12)"

Aquí está el código pascal:

function testarm(a,b:integer):integer; cdecl; external "testC.o";

Procedure testC;
Begin
  testarm(1,2);
end;

function BackToPascal(a,b:integer): integer; cdecl;
  Begin
  result := a+b;
end;

......

exports
  BackToPascal;

Y aquí está el código C:

extern int BackToPascal(int a,int b);

extern int testarm(int a,int b)
{
   int i;
   i = BackToPascal(a,b);
   return i+1;
}

En Android, así es como estoy compilando (está funcionando):

..."arm-linux-androideabi-gcc.exe" -c test.c -o test.o -O3 -mfloat-abi=softfp -mfpu=neon -marm -march=armv7-a -mtune=cortex-a8

En ios:

xcrun -sdk iphoneos clang -c -arch armv7 test.c -O3 -mfpu=neon -mtune=cortex-a8 -marm -march=armv7-a -mfloat-abi=softfp

Sospecho que mi configuración de xcode es incorrecta, pero no puedo entender por qué.

Cuando depuro, el error se produce al llamar a testC en testarm cuando se llama a BackToPascal (en "bl 0x8b8390 Xgobj.BackToPascal (int, int)"). En Android funciona perfecto, sin embargo, el bl no llama directamente a BackToPascal , pero el siguiente código:

75A82D94 12C68FE2         add r12, pc, #18874368 ; 0x1200000
75A82D98 73CA8CE2         add r12, r12, #471040 ; 0x73000
75A82D9C 40F2BCE5         ldr pc, [r12, #576]! ; 0x240

Que entran en BackToPascal


Answers

El código parece correcto y su manejo de convención de llamadas es, a mis ojos, perfectamente correcto.

Creo que es posible que hayas topado con un error posible / rumorado en el sonido ARM de Apple, donde llamar a una función estática (que puede suceder detrás de las escenas, por ejemplo, para la conversión de tipo) de una función estática puede causar daños en la pila. No lo está haciendo directamente, pero las funciones externas pueden implementarse a través de un stub que llama a una función estática anónima que contiene la implementación.

Puede intentar que su función externa sea un contenedor que solo llame a una función de implementación no estática.


Una advertencia de que una expresión condicional es constante puede ser útil. En muchos casos, puede apuntar a un error lógico en su código.

Por ejemplo, si escribes algo como:

if (x != NULL) { /* ... */ }

donde x es un objeto de matriz, la expresión es válida, pero la expresión x decae en un puntero al elemento inicial de la matriz, que no puede ser un puntero nulo. No sé si eso produce el mismo error, pero es un ejemplo del mismo tipo de cosas.

Por supuesto que no siempre es útil. En tu caso, la

do { /* ... */ } while (0)

idioma es la mejor manera de escribir una definición de macro que está diseñada para usarse en un contexto que requiere una declaración. Es probable que el uso de while (0) en otro contexto sea un error lógico [*].

Es desafortunado que su compilador no lo reconozca como un idioma común. Generar buenas advertencias es complicado; El compilador debe ir más allá de las reglas del lenguaje e inferir la intención del programador.

En este caso, el uso de algún método específico del compilador para suprimir la advertencia (siempre que no rompa el código de otros compiladores) es probablemente el mejor enfoque. Usar una opción de línea de comando para suprimir la advertencia en todos los casos sería excesivo; podría pasar por alto advertencias válidas en otras partes de su código.

Aparentemente, escribir while (0,0) lugar de while (0) evita la advertencia. Si lo hace, debe agregar un comentario que indique claramente que es una solución para su compilador en particular. No hay ninguna razón particular por la que un compilador no deba advertir sobre while (0,0) o cualquier otro código equivalente.

[*] Puede tener sentido escribir una instrucción do { /* ... */ } while (0) si quieres poder usar break para saltar fuera de ella.





ios c delphi pascal delphi-xe6