Accessing to C object properties from Swift 4 - ios

I imported the libxml2 C library into a pure Swift project successfully but now I'm facing a new problem. I want to access to the properties of an xmlNode C Type, which is declared like this at the libxml library
struct _xmlNode {
void *_private; /* application data */
xmlElementType type; /* type number, must be second ! */
const xmlChar *name; /* the name of the node, or the entity */
struct _xmlNode *children; /* parent->childs link */
struct _xmlNode *last; /* last child link */
struct _xmlNode *parent; /* child->parent link */
struct _xmlNode *next; /* next sibling link */
struct _xmlNode *prev; /* previous sibling link */
struct _xmlDoc *doc; /* the containing document */
/* End of common part */
xmlNs *ns; /* pointer to the associated namespace */
xmlChar *content; /* the content */
struct _xmlAttr *properties;/* properties list */
xmlNs *nsDef; /* namespace definitions on this node */
void *psvi; /* for type/PSVI informations */
unsigned short line; /* line number */
unsigned short extra; /* extra data for XPath/XSLT */
};
For example, I want to access to the name property of a xmlNode object named node. I know that, using objective-C, that can be done like this node->name, but that is not allowed on Swift.
I found the move() function inside the object so I can do node.move().name but I'm not sure if that is the way to go.
Also, how can I cast the C types to Swift types easily?
Anyone can point me to the right way?
Thanks.

Related

How to create a linked list using a struct inside the node element

I tried to create a linked list, using a node that had a structure inside it to hold the info data. Whenever I try to do that , I have a compiled error telling me that I am using an "incomplete" type, and I am not sure why.
The exact error I have is the following:
main.c: In function ‘createList’:
main.c:53:46: error: invalid application of ‘sizeof’ to incomplete type ‘typeNode’ {aka ‘struct StructInfoNodo’}
53 | if ((new_node = (typeNode *) malloc (sizeof (typeNode))) == NULL)
| ^~~~~~~~
main.c:59:9: error: dereferencing pointer to incomplete type ‘typeNode’ {aka ‘struct StructInfoNodo’}
59 | new_node->info.idCell=nodeinfo.idCell;
| ^~
main2.c:67:5: warning: statement with no effect [-Wunused-value]
67 | list->num_nodes;
| ~~~~^~~~~~~~~~~
In my code, I have a createList funtion, which tries to create the first node of the list, using some sample data. However, I am unable to the initial malloc, seems it does not recognize the new type that was defined (typeNet) to hold the info inside a structure.
I was using for that the following instruct: new_node = (typeNode *) malloc (sizeof (typeNode))
and after that, I was trying to do new_node->info.idCell=nodeinfo.idCell;
That lines result in the errors shown above.
Any idea on how I can solve it, and be able to write info on the node?
Please find below the complete code:
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#define MAXCHAR 80
struct structInfoNet
{
int idCell;
char MacAddress[MAXCHAR];
char Essid[MAXCHAR];
char Mode[MAXCHAR];
int Channel;
};
typedef struct structInfoNet typeNet;
struct structInfoNode
{
typeNet info;
struct structInfoNode* nextNode;
};
typedef struct StructInfoNodo typeNode;
/* Struct to store pointers to firs & last element linked list */
struct structInfoLista {
typeNode *firstNode;
typeNode *lastNode;
int num_nodes;
};
typedef struct structInfoLista typeInfoList;
/* Initialitate frist & last elements linked list */
void initLinkedList (typeInfoList *list){
list->firstNode = NULL;
list->lastNode = NULL;
list->num_nodes= 0;
}
/* Insert First Element on the List (CreateList) */
int createList (typeInfoList * list, typeNet nodeinfo) {
typeNode *new_node;
if ((new_node = (typeNode *) malloc (sizeof (typeNode))) == NULL)
{
printf ("Error. Unable to create node");
return -1;
}
new_node->info.idCell=nodeinfo.idCell;
new_node->nextNode = NULL;
list->firstNode = new_node;
list->lastNode = new_node;
list->num_nodes;
return 0;
}
int main()
{
typeNet net;
typeInfoList *list;
// Get memory to store struct with pointers to first & last Nodes
if ((list = (typeInfoList *) malloc (sizeof (typeInfoList))) == NULL)
{
printf ("Error!! Unable to get memory");
exit (1);
}
//Create auxiliar list to store pointers to first & last nodes
initLinkedList (list);
// Sample data to add to first element of the list
net.idCell=5;
//Create initial linked list (first element)
createList (list, net);
}
this
typedef struct StructInfoNodo typeNode;
should be
typedef struct structInfoNodo typeNode;

JNA to Go DLL - How do I get String returned from Go Func?

I have a Java program that is using JNA to call a Go Func. Here's the Interface to the Go func in Java:
public interface GPG extends Library {
// GoString class maps to: C type struct { const char *p; GoInt n; }
public class GoString extends Structure {
public static class ByValue extends GoString implements Structure.ByValue {}
public String p;
public long n;
protected List getFieldOrder(){
return Arrays.asList(new String[]{"p","n"});
}
}
// Foreign functions
public GoString.ByValue decrypt(GoString.ByValue encString, GoString.ByValue secretKeyring, GoString.ByValue passphrase);
}
The func signature in Go is:
func decrypt(encString string, secretKeyring string, passphrase string) string
The Go generated C header has:
/* Created by "go tool cgo" - DO NOT EDIT. */
/* package command-line-arguments */
#line 1 "cgo-builtin-prolog"
#include <stddef.h> /* for ptrdiff_t below */
#ifndef GO_CGO_EXPORT_PROLOGUE_H
#define GO_CGO_EXPORT_PROLOGUE_H
typedef struct { const char *p; ptrdiff_t n; } _GoString_;
#endif
/* Start of preamble from import "C" comments. */
/* End of preamble from import "C" comments. */
/* Start of boilerplate cgo prologue. */
#line 1 "cgo-gcc-export-header-prolog"
#ifndef GO_CGO_PROLOGUE_H
#define GO_CGO_PROLOGUE_H
typedef signed char GoInt8;
typedef unsigned char GoUint8;
typedef short GoInt16;
typedef unsigned short GoUint16;
typedef int GoInt32;
typedef unsigned int GoUint32;
typedef long long GoInt64;
typedef unsigned long long GoUint64;
typedef GoInt64 GoInt;
typedef GoUint64 GoUint;
typedef __SIZE_TYPE__ GoUintptr;
typedef float GoFloat32;
typedef double GoFloat64;
typedef float _Complex GoComplex64;
typedef double _Complex GoComplex128;
/*
static assertion to make sure the file is being used on architecture
at least with matching size of GoInt.
*/
typedef char _check_for_64_bit_pointer_matching_GoInt[sizeof(void*)==64/8 ? 1:-1];
typedef _GoString_ GoString;
typedef void *GoMap;
typedef void *GoChan;
typedef struct { void *t; void *v; } GoInterface;
typedef struct { void *data; GoInt len; GoInt cap; } GoSlice;
#endif
/* End of boilerplate cgo prologue. */
#ifdef __cplusplus
extern "C" {
#endif
extern GoString decrypt(GoString p0, GoString p1, GoString p2);
#ifdef __cplusplus
}
#endif
I call the Go Func from Java using this code:
GPG gpg = (GPG) Native.loadLibrary("C:/lib/gpg.dll", GPG.class);
GPG.GoString.ByValue encString = new GPG.GoString.ByValue();
encString.p = value;
encString.n = encString.p.length();
GPG.GoString.ByValue secretKeyring = new GPG.GoString.ByValue();
secretKeyring.p = "c:/gnupg/secring.gpg";
secretKeyring.n = secretKeyring.p.length();
GPG.GoString.ByValue passphrase = new GPG.GoString.ByValue();
passphrase.p = "SecretPassPhrase";
passphrase.n = passphrase.p.length();
GPG.GoString.ByValue decValue = gpg.decrypt(encString, secretKeyring, passphrase);
Clearly the func is being called and processes up to the return of the result string. But it then produces: "panic: runtime error: cgo result has Go pointer"
How do I get a String result back from Go?
Using go version go1.10 windows/amd64, JNA 4.5.1, Java 1.8.0_152
Your GO function should looks like this:
//export decrypt
func decrypt(encString string, secretKeyring string, passphrase string) *C.char {
//... your code here
var str string = "returning string"
return C.CString(str)
}
Java Interface:
public String decrypt(GoString.ByValue encString, GoString.ByValue secretKeyring, GoString.ByValue passphrase);
Your const char * in _GoString_ should use a Pointer instead, then use Pointer.getString() with the provided offset to obtain the actual string.
If Go itself is rejecting a string return value, you'll likely have to instead populate a buffer provided by the caller.

How to create a table of linker-resolved data in non-dirty memory

I would like to create a table of data, and keep it in non-dirty memory (so that the table doesn't contribute to them memory usage of the app on iOS and related platforms (tvOS/watchOS)).
The table is an array of two pieces of data: Objective-C class and a numeric value:
#include <Foundation/Foundation.h>
struct TypeMap {
Class class;
int value;
};
I'd like to do something like this:
struct TypeMap map [] = {
{ [NSObject class], 0x1234 }
};
but that obviously doesn't work, clang complains with:
test.m:9:4: error: initializer element is not a compile-time constant
{ [NSObject class], 0x1234 }
^~~~~~~~~~~~~~~~
which makes total sense of course, since [NSObject class] is not a compile-time constant.
But there is a symbol that the dynamic loader is able to resolve: _OBJC_CLASS_$_NSObject, which leads me to something like this:
extern Class OBJC_CLASS_$_NSObject;
struct TypeMap map [] = {
{ OBJC_CLASS_$_NSObject, 0x1234 }
};
The idea being that the dynamic linker can resolve the symbol at runtime, and then mark the memory as read-only (the same way it works for normal code).
Unfortunately it runs into the same problem:
test.m:11:4: error: initializer element is not a compile-time constant
{ OBJC_CLASS_$_NSObject, 0x1234 }
^~~~~~~~~~~~~~~~~~~~~
I'm certain I can express this in assembly code, but I'd like to avoid assembly if possible and stick with Objective-C (no need to implement it once per platform).
Am I completely off track here? Is this even possible?
UPDATE
Working version:
// clang test.m -framework Foundation
#include <Foundation/Foundation.h>
#include <objc/objc.h>
#include <objc/runtime.h>
struct TypeMap {
Class class;
int value;
};
extern void* OBJC_CLASS_$_NSObject;
const struct TypeMap map [] = {
{ (Class) &OBJC_CLASS_$_NSObject, 0x1234 },
};
int main ()
{
printf ("%s %p %i\n", class_getName (map[0].class), map [0].class, map [0].value);
return 0;
}
If I understand correctly, a Class in Objective-C is an aggregate type, in the sense in which the C standard uses that term. Then, given
struct TypeMap {
Class class;
int value;
};
extern Class OBJC_CLASS_$_NSObject;
struct TypeMap map [] = {
{ OBJC_CLASS_$_NSObject, 0x1234 }
};
you are asking the dynamic loader to copy the aggregate into your data structure, at load time, which is not a feature that it has.
What you should be able to do instead is have your TypeMap contain pointers to the OBJC_CLASS_$_... symbols:
struct TypeMap {
Class *class;
int value;
};
extern Class OBJC_CLASS_$_NSObject;
const struct TypeMap map[] = {
{ &OBJC_CLASS_$_NSObject, 0x1234 },
// ...
};
Give that a whirl and see how it goes.
(Note the added const on the declaration of map — you need that to get this data structure put in the read-only data segment in the first place.)

What is the type of pthread_mutex_t?

From: https://www.sourceware.org/pthreads-win32/manual/pthread_mutex_init.html
Variables of type pthread_mutex_t can also be initialized statically,
So, what is the type of pthread_mutex_t?
That is the type. The implementation underneath is often a struct and you can look in the header files if you really care about the specific implementation of the library you're using, but those details don't matter for using it, you just care about the pthread_mutex_t type.
pthread_mutex_t mymutex = PTHREAD_MUTEX_INITIALIZER;
From pthreadtypes.h, in my Linux distribution its definition is pretty clear as a typedef for a union, as defined below:
/* Data structures for mutex handling. The structure of the attribute
type is not exposed on purpose. */
typedef union
{
struct __pthread_mutex_s
{
int __lock;
unsigned int __count;
int __owner;
/* KIND must stay at this position in the structure to maintain
binary compatibility. */
int __kind;
unsigned int __nusers;
__extension__ union
{
int __spins;
__pthread_slist_t __list;
};
} __data;
char __size[__SIZEOF_PTHREAD_MUTEX_T];
long int __align;
} pthread_mutex_t;
You'll want to use it as their defined type, pthread_mutex_t of course -- since this type will vary by OS / distribution / etc.
pthread_mutex_t is a type, so it doesn't have a type itself. If you are curious about what this type is an alias for, on my machine I have:
struct _opaque_pthread_mutex_t {
long __sig;
char __opaque[__PTHREAD_MUTEX_SIZE__];
};
and then
typedef struct _opaque_pthread_mutex_t __darwin_pthread_mutex_t;
and finally:
typedef __darwin_pthread_mutex_t pthread_mutex_t;

what does EXC BAD ACCESS MEAN? What does it mean in reference to my code?

What does my error mean? How can I fix it?
See here for a photo of the error when I try to run the program ...
http://postimg.org/image/horh6d26j/
My program is attempting to remove the last element of a double linked list and insert it at the front
I am only trying to execute the backToFront function.
The activity is a past prac exam at my university from 2011(?)
I am trying to complete it in preparation for my prac exam -- which is in two days
(aaahhhhhhh!!!!!!)
/*
* backToFront.c
* comp1917 pracExam #2 2011s1 UNSW
*
* Author: WRITE YOUR NAME HERE
* Date: 21 June 2011
* License: Public Domain
*/
// Implement the backToFront function below
// so that it moves the last node in a non-empty linked list
// of nodes to be the first node in the list, leaving the
// relative position of all the other nodes unchanged.
// You may assume the input list contains at least one node.
//
// Your function should do the moving by changing pointers
// in the nodes and list structs, (don't use malloc or make
// any new nodes)
//
// Your function should return the new list.
//
// You need to pass the tests in testBackToFront.c
//
// Compile and run the tests using
// gcc -Wall -Werror -O -o tester backtToFront.c testBackToFront.c
// ./tester
//
// When a test fails look in the testBackToFront.c file to see
// what the test was testing. There are 3 tests in that file.
//
// Once you have passed all the tests you have finished.
#include <stdio.h>
#include <stdlib.h>
#include <assert.h>
#include "backToFront.h"
list backToFront (list items) {
assert (items.first != NULL);
nodePtr current = items.first;
nodePtr previous = NULL;
while (current != NULL){
previous = current;
current = current->rest;
}
current->rest = items.first;
items.first = current;
previous->rest = NULL;
return items;
}
/*
* backToFront.h
* pracExam 2011
*
* Created by Richard Buckland on 26/07/09.
* Modified by David Collien on 20/06/11.
* Copyright 2011. All rights reserved.
*
*/
// DO NOT ALTER OR SUBMIT THIS FILE
// we will use our own copy when marking
typedef struct _node *nodePtr;
typedef struct _list {
nodePtr first;
} list;
// For le sorution, add /samplesolutions at the end of your url
typedef struct _node {
int value;
nodePtr rest;
} node;
// given a node (*item) and a list of nodes (items)
// this function takes the last node of the list
// and moves it to be the first node in the list.
//
// the function returns the altered list.
//
// (note that the function does not create new nodes
// or change the value field of existing nodes.)
list backToFront (list items);
Most likely out of bounds (no item at that index). Make sure the array isn't null

Resources