Page 1 of 1

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

Posted: Mon Apr 10, 2017 1:15 pm
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

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

Posted: Mon Apr 10, 2017 1:43 pm
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

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

Posted: Tue Apr 11, 2017 7:44 pm
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()  ) 

 

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

Posted: Wed Apr 12, 2017 5:18 pm
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 ;-)

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

Posted: Wed Apr 12, 2017 8:20 pm
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 )"
    
    }
           
}

 

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

Posted: Thu Apr 13, 2017 7:20 am
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

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

Posted: Thu Apr 13, 2017 7:21 am
by Antonio Linares
Puedes copiar aqui el contenido de foo-Swift.h ?

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

Posted: Thu Apr 13, 2017 10:46 am
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

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

Posted: Thu Apr 13, 2017 11:09 am
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!

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

Posted: Thu Apr 13, 2017 1:10 pm
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

 

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

Posted: Fri Apr 14, 2017 8:59 am
by Antonio Linares
supongo que ambos usan la máquina virtual LLVM

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

Posted: Fri Apr 14, 2017 11:53 am
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

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

Posted: Fri Apr 14, 2017 12:46 pm
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 )  ]  ) ;
 }

 

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

Posted: Fri Apr 14, 2017 7:44 pm
by Antonio Linares
muy bien :-)