enviando datos desde una función en swift ( experimental )

Post Reply
User avatar
mastintin
Posts: 1502
Joined: Thu May 27, 2010 2:06 pm

enviando datos desde una función en swift ( experimental )

Post by mastintin »

La función Swift

Code: Select all


import Foundation

@objc public class foo : NSObject {
        
    @objc func printSome() -> String {
        
         return "Print line System" ;
        
    }
    
}

 
Image
User avatar
cnavarro
Posts: 5792
Joined: Wed Feb 15, 2012 8:25 pm
Location: España

Re: enviando datos desde una función en swift ( experimental )

Post by cnavarro »

mastintin wrote:La función Swift

Code: Select all


import Foundation

@objc public class foo : NSObject {
        
    @objc func printSome() -> String {
        
         return "Print line System" ;
        
    }
    
}

 
Image
Qué bueno Manuel, genial
C. Navarro
Hay dos tipos de personas: las que te hacen perder el tiempo y las que te hacen perder la noción del tiempo
Si alguien te dice que algo no se puede hacer, recuerda que esta hablando de sus limitaciones, no de las tuyas.
User avatar
mastintin
Posts: 1502
Joined: Thu May 27, 2010 2:06 pm

Re: enviando datos desde una función en swift ( experimental )

Post by mastintin »

Aun mas rebuscado ... y si uso una función de harbour dentro de una función swift y devuelvo el resultado a harbour ?
A ver si se entiende el tema que es un poco complicado ...

Código en archivo swift ...

Code: Select all


import Foundation
import AppKit

// Le decimos a swift que la  función seconds() no tiene parámetros y devuelve un Double  y la renombrados como HBSEC() para usarla en Swift 
@_silgen_name("HB_FUN_SECONDS")
func HBSEC()-> CDouble

@objc public class foo : NSObject {
    
   // creamos un metodo de foo llamado SECSW que usa seconds(),  en este caso solo devuelve su resultado ( podría hacer lo cualquier cosa en swift ) 
    @objc public func SECSW() -> CDouble {
            let r = HBSEC()
       return r
    }
         
}

 
Código en archivo objC para devolver a harbour el resultado final ...

Code: Select all

// esto seria la nueva función Harbour final que devuelve el resultado de las operaciones realizadas en swift ...

HB_FUNC( NEWSECONDS )
{
   foo * sis = [[ foo alloc] init] ;
    hb_retnd( [sis SECSW ] ) ;        
}

 
En el programa fivemac ...

Code: Select all


Msginfo(  NewSeconds()  ) 

 
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: enviando datos desde una función en swift ( experimental )

Post by Antonio Linares »

Manuel,

totalmente sorprendido :-)

Que extensión de fichero usas para swift ?

Cómo lo compilas ?

Cómo lo enlazas ?

Cómo es posible que puedan enlazarse ? Entiendo que swift usa su propia máquina virtual

Extraordinario como siempre ;-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
mastintin
Posts: 1502
Joined: Thu May 27, 2010 2:06 pm

Re: enviando datos desde una función en swift ( experimental )

Post by mastintin »

Antonio Linares wrote: Que extensión de fichero usas para swift ?
Los Archivos swift usan la extension .Swift
Antonio Linares wrote:
Cómo lo compilas ?
Cómo lo enlazas ?
Para el experimento he realizado lo siguiente ..
Por un lado he creado _ nuevas dentro de la estructura de fivemac
una es objs donde van a parar los obj de archivos swift
otra es swift dentro de source que es donde he colocado el archivo swift experimental y donde van a parar los archivos auxiliares generados .

he creado dos archivos nuevos para no molestar demasiado a lo que tenemos en fivemac uno llamado foo.swift que he colocado en la capeta swift y otro llamado swfun.m que he colocado en winapi y que tiene el código para recoger los resultados ...

He modificado nuestro make file añadiendo :

SWIFTFLAGS = -I../include -sdk $(shell xcrun --show-sdk-path -sdk macosx)

una nueva sección ...

SWIFT_OBJS = ./objs/foo.o

y una nueva directiva de compilación

./objs/%.o : ./source/swift/%.swift
if [ ! -d "objs" ]; then mkdir objs; fi
swiftc -frontend -c -color-diagnostics -primary-file $< \
-module-name Bridgette \
$(SWIFTFLAGS) -emit-module -emit-module-path ./source/swift/$*.swiftmodule \
-emit-objc-header-path ./source/swift/$*-Swift.h \
-enable-testing -enable-objc-interop -parse-as-library \
-o $@
if [ ! -d "lib" ]; then mkdir lib; fi
ar rc ./lib/libfivec.a $@

Esto hace que los archivos colocados en la carpeta swift sean compilados , que generen un archivo .o y que generen un archivo cabecera <archivo>-Swift.h .
Este archivo de cabecera debe incluirse en el archivo .m que quiera usar funciones del archivo swift .

Se tendria que colocar al principio ya que si no esta generado el archivo .o de swift y su cabecera el archivo .m que contenga su código fallará al compilar . :D

Dentro de swift las funciones a usar las he colocado dentro de una clase publica swift y he creado métodos parta las funciones.

Todo esto es un experimento y está muy verde sobre todo el tema de paso de paramentos y sus tipos .
Apple ha apostado por swift en detrimento de objC , esta claro que se puede mezclar código swift con código objC .
Ya tenemos los comandos para poder compilar desde linea de comandos o desde un makefile .
Swift tiene un metodo relativamente simple para poder usar una función objC dentro de su código y debemos pensar que tanto las funciones internas de Harbour como nuestras funciones C son al final funciones C o lo que es lo mismo ObjC .
Desde una función C también podemos recuperar valores de funciones completas de swift y así poder usarlas dentro de harbour .

Uso simple ( sin usar funciones C dentro de swift )

archivo swfun.m

Code: Select all

#include <fivemac.h>
#import "../swift/foo-Swift.h"

HB_FUNC( HELLOCC )
{
    NSString * stringIni = hb_NSSTRING_par( 1 ) ;
    foo * sis = [[ foo alloc] init] ;
//   NSString * string =   [sis helloWithName:@"manuel" ]  ;
    NSString * string =   [sis helloWithName: stringIni ]  ;
    hb_retc(  [ string cStringUsingEncoding : NSUTF8StringEncoding ] );
     
}

 
archivo foo.swift

Code: Select all


import Foundation

@objc public class foo : NSObject {
  
       @objc public func hello( name: String ) -> String {
          return "Hello querido \( uno )"
    
    }
           
}

 
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: enviando datos desde una función en swift ( experimental )

Post by Antonio Linares »

Muy interesante, muchas gracias :-)

Eso quiere decir que la maquina virtual que usa Swift es la misma que usa Objective-C

eso parece
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: enviando datos desde una función en swift ( experimental )

Post by Antonio Linares »

Puedes copiar aqui el contenido de foo-Swift.h ?
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
mastintin
Posts: 1502
Joined: Thu May 27, 2010 2:06 pm

Re: enviando datos desde una función en swift ( experimental )

Post by mastintin »

Antonio Linares wrote:Puedes copiar aqui el contenido de foo-Swift.h ?
El archivo fío-Swift.h es largo trae un montón de definiciones y al final la pare interensante es un fichero de cabecera de objectiveC donde define la clase foo como si fuera c .
Cuando llegue a casa te lo envío pero lo bueno de todo esto es que con el código que he puesto en el makefile ,ese archivo es generado automáticamente por el compilador y no tenemos que preocuparnos por el
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: enviando datos desde una función en swift ( experimental )

Post by Antonio Linares »

> un fichero de cabecera de objectiveC donde define la clase foo como si fuera c

eso es lo más interesante, para ver como lo adapta a Objective-C

gracias!
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
mastintin
Posts: 1502
Joined: Thu May 27, 2010 2:06 pm

Re: enviando datos desde una función en swift ( experimental )

Post by mastintin »

Antonio Linares wrote:> un fichero de cabecera de objectiveC donde define la clase foo como si fuera c

eso es lo más interesante, para ver como lo adapta a Objective-C

gracias!
pongo aquí el fichero completo , lo importante está al final ...
una cosa ...
SWIFT_CLASS("_TtC9Bridgette3foo")
el nombre Bridgette no es casualidad ya que en el make file yo he puesto esto : -module-name Bridgette

Code: Select all

// Generated by Apple Swift version 3.1 (swiftlang-802.0.51 clang-802.0.41)
#pragma clang diagnostic push

#if defined(__has_include) && __has_include(<swift/objc-prologue.h>)
# include <swift/objc-prologue.h>
#endif

#pragma clang diagnostic ignored "-Wauto-import"
#include <objc/NSObject.h>
#include <stdint.h>
#include <stddef.h>
#include <stdbool.h>

#if !defined(SWIFT_TYPEDEFS)
# define SWIFT_TYPEDEFS 1
# if defined(__has_include) && __has_include(<uchar.h>)
#  include <uchar.h>
# elif !defined(__cplusplus) || __cplusplus < 201103L
typedef uint_least16_t char16_t;
typedef uint_least32_t char32_t;
# endif
typedef float swift_float2  __attribute__((__ext_vector_type__(2)));
typedef float swift_float3  __attribute__((__ext_vector_type__(3)));
typedef float swift_float4  __attribute__((__ext_vector_type__(4)));
typedef double swift_double2  __attribute__((__ext_vector_type__(2)));
typedef double swift_double3  __attribute__((__ext_vector_type__(3)));
typedef double swift_double4  __attribute__((__ext_vector_type__(4)));
typedef int swift_int2  __attribute__((__ext_vector_type__(2)));
typedef int swift_int3  __attribute__((__ext_vector_type__(3)));
typedef int swift_int4  __attribute__((__ext_vector_type__(4)));
typedef unsigned int swift_uint2  __attribute__((__ext_vector_type__(2)));
typedef unsigned int swift_uint3  __attribute__((__ext_vector_type__(3)));
typedef unsigned int swift_uint4  __attribute__((__ext_vector_type__(4)));
#endif

#if !defined(SWIFT_PASTE)
# define SWIFT_PASTE_HELPER(x, y) x##y
# define SWIFT_PASTE(x, y) SWIFT_PASTE_HELPER(x, y)
#endif
#if !defined(SWIFT_METATYPE)
# define SWIFT_METATYPE(X) Class
#endif
#if !defined(SWIFT_CLASS_PROPERTY)
# if __has_feature(objc_class_property)
#  define SWIFT_CLASS_PROPERTY(...) __VA_ARGS__
# else
#  define SWIFT_CLASS_PROPERTY(...)
# endif
#endif

#if defined(__has_attribute) && __has_attribute(objc_runtime_name)
# define SWIFT_RUNTIME_NAME(X) __attribute__((objc_runtime_name(X)))
#else
# define SWIFT_RUNTIME_NAME(X)
#endif
#if defined(__has_attribute) && __has_attribute(swift_name)
# define SWIFT_COMPILE_NAME(X) __attribute__((swift_name(X)))
#else
# define SWIFT_COMPILE_NAME(X)
#endif
#if defined(__has_attribute) && __has_attribute(objc_method_family)
# define SWIFT_METHOD_FAMILY(X) __attribute__((objc_method_family(X)))
#else
# define SWIFT_METHOD_FAMILY(X)
#endif
#if defined(__has_attribute) && __has_attribute(noescape)
# define SWIFT_NOESCAPE __attribute__((noescape))
#else
# define SWIFT_NOESCAPE
#endif
#if defined(__has_attribute) && __has_attribute(warn_unused_result)
# define SWIFT_WARN_UNUSED_RESULT __attribute__((warn_unused_result))
#else
# define SWIFT_WARN_UNUSED_RESULT
#endif
#if !defined(SWIFT_CLASS_EXTRA)
# define SWIFT_CLASS_EXTRA
#endif
#if !defined(SWIFT_PROTOCOL_EXTRA)
# define SWIFT_PROTOCOL_EXTRA
#endif
#if !defined(SWIFT_ENUM_EXTRA)
# define SWIFT_ENUM_EXTRA
#endif
#if !defined(SWIFT_CLASS)
# if defined(__has_attribute) && __has_attribute(objc_subclassing_restricted)
#  define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_CLASS_EXTRA
#  define SWIFT_CLASS_NAMED(SWIFT_NAME) __attribute__((objc_subclassing_restricted)) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
# else
#  define SWIFT_CLASS(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
#  define SWIFT_CLASS_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_CLASS_EXTRA
# endif
#endif

#if !defined(SWIFT_PROTOCOL)
# define SWIFT_PROTOCOL(SWIFT_NAME) SWIFT_RUNTIME_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
# define SWIFT_PROTOCOL_NAMED(SWIFT_NAME) SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_PROTOCOL_EXTRA
#endif

#if !defined(SWIFT_EXTENSION)
# define SWIFT_EXTENSION(M) SWIFT_PASTE(M##_Swift_, __LINE__)
#endif

#if !defined(OBJC_DESIGNATED_INITIALIZER)
# if defined(__has_attribute) && __has_attribute(objc_designated_initializer)
#  define OBJC_DESIGNATED_INITIALIZER __attribute__((objc_designated_initializer))
# else
#  define OBJC_DESIGNATED_INITIALIZER
# endif
#endif
#if !defined(SWIFT_ENUM)
# define SWIFT_ENUM(_type, _name) enum _name : _type _name; enum SWIFT_ENUM_EXTRA _name : _type
# if defined(__has_feature) && __has_feature(generalized_swift_name)
#  define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) enum _name : _type _name SWIFT_COMPILE_NAME(SWIFT_NAME); enum SWIFT_COMPILE_NAME(SWIFT_NAME) SWIFT_ENUM_EXTRA _name : _type
# else
#  define SWIFT_ENUM_NAMED(_type, _name, SWIFT_NAME) SWIFT_ENUM(_type, _name)
# endif
#endif
#if !defined(SWIFT_UNAVAILABLE)
# define SWIFT_UNAVAILABLE __attribute__((unavailable))
#endif
#if !defined(SWIFT_UNAVAILABLE_MSG)
# define SWIFT_UNAVAILABLE_MSG(msg) __attribute__((unavailable(msg)))
#endif
#if !defined(SWIFT_AVAILABILITY)
# define SWIFT_AVAILABILITY(plat, ...) __attribute__((availability(plat, __VA_ARGS__)))
#endif
#if !defined(SWIFT_DEPRECATED)
# define SWIFT_DEPRECATED __attribute__((deprecated))
#endif
#if !defined(SWIFT_DEPRECATED_MSG)
# define SWIFT_DEPRECATED_MSG(...) __attribute__((deprecated(__VA_ARGS__)))
#endif
#if defined(__has_feature) && __has_feature(modules)
@import ObjectiveC;
#endif

#pragma clang diagnostic ignored "-Wproperty-attribute-mismatch"
#pragma clang diagnostic ignored "-Wduplicate-method-arg"

SWIFT_CLASS("_TtC9Bridgette3foo")
@interface foo : NSObject
- (NSString * _Nonnull)helloWithName:(NSString * _Nonnull)name SWIFT_WARN_UNUSED_RESULT;
- (nonnull instancetype)init OBJC_DESIGNATED_INITIALIZER;
@end

#pragma clang diagnostic pop

 
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: enviando datos desde una función en swift ( experimental )

Post by Antonio Linares »

supongo que ambos usan la máquina virtual LLVM
regards, saludos

Antonio Linares
www.fivetechsoft.com
User avatar
mastintin
Posts: 1502
Joined: Thu May 27, 2010 2:06 pm

Re: enviando datos desde una función en swift ( experimental )

Post by mastintin »

Antonio Linares wrote:supongo que ambos usan la máquina virtual LLVM
los dos generan después de varios procesos archivos con llvm bitcode
User avatar
mastintin
Posts: 1502
Joined: Thu May 27, 2010 2:06 pm

Re: enviando datos desde una función en swift ( experimental )

Post by mastintin »

Sigo con los experimentos ... he intentado hacer algo un paso mas complejo ...
Replicar la función que tenemos para poner archivos en la papelera ( MOVETOTRASH ) en swift y intentar llamarla desde un programa ...
He querido saltarme también la conversion de const char* a NSString y pásarla directamente a Swift y parece que funciona bien.

en swift :

Code: Select all

  @objc public func totrash( file: UnsafePointer<CChar> ) -> Bool {
        
        let s = String(cString: file )
        var lresult = false
        let fileM = FileManager.default
        let urlPath = NSURL.fileURL(withPath: s )
        
        if fileM.isDeletableFile(atPath:s){
            do {
                try fileM.trashItem(at:urlPath, resultingItemURL: nil )
                lresult = true
            }
                catch  {
                lresult = false
                
            }

        }
        
        return lresult
     }

 
en M file ...

Code: Select all


HB_FUNC( MOVETOTRASH3 )
{
  hb_retl( [[[ foo alloc] init] totrashWithFile: hb_parc( 1 )  ]  ) ;
 }

 
User avatar
Antonio Linares
Site Admin
Posts: 37481
Joined: Thu Oct 06, 2005 5:47 pm
Location: Spain
Contact:

Re: enviando datos desde una función en swift ( experimental )

Post by Antonio Linares »

muy bien :-)
regards, saludos

Antonio Linares
www.fivetechsoft.com
Post Reply