How to write #define expressions with nested brackets in cython? - python-3.x

C expression:
#define EFX_REVERB_PRESET_GENERIC \
{ 1.0000f, 1.0000f, 0.3162f, 0.8913f, 1.0000f, 1.4900f, 0.8300f, 1.0000f, 0.0500f, 0.0070f, { 0.0000f, 0.0000f, 0.0000f }, 1.2589f, 0.0110f, { 0.0000f, 0.0000f, 0.0000f }, 0.2500f, 0.0000f, 0.2500f, 0.0000f, 0.9943f, 5000.0000f, 250.0000f, 0.0000f, 0x1 }
I want to define this expression in the .pxd file.
I have to pass this expression as parameters to some C functions. So I don't use it for Python.
Source: OpenAL-Soft: https://github.com/kcat/openal-soft/blob/master/include/AL/efx-presets.h#L37

It's worth realising that not everything has a direct translation from C to Cython. In this case EFX_REVERB_PRESET_GENERIC can't really be defined using a type because it isn't a type - it's just a collection of brackets and numbers. These brackets and numbers are only valid in a small number of places:
void other_func(WhateverTheStructIsCalled s);
void func() {
WhateverTheStructIsCalled s = EFX_REVERB_PRESET_GENERIC; // OK
s = EFX_REVERB_PRESET_GENERIC; // wrong - not an initialization
other_func(EFX_REVERB_PRESET_GENERIC); // also doesn't work
}
Therefore it doesn't really fit into Cython's model so you can't wrap it directly.
What I'd do is write a small C wrapper yourself. You can do this with Cython's "inline C code" function:
cdef extern from *:
"""
WhateverTheStructIsCalled get_EFX_REVERB_PRESET_GENERIC(void) {
WhateverTheStructIsCalled s = EFX_REVERB_PRESET_GENERIC;
return s;
}
"""
WhateverTheStructIsCalled get_EFX_REVERB_PRESET_GENERIC()
Then use get_EFX_REVERB_PRESET_GENERIC() to call this function and get the relevant initialized structure.

Related

Does Malloc allocate the correct space?

I have a structure which is passed to a function. There some values should be changed. Back in the main I should read out the new values of my structure.
In a sample project it works EASILY!
In my main code in Visual Studio Code with ARM Cortex M3 and a crazy library it DOESNT WORK
(update: something must be wrong with compiler: I checked it hard and observed that not all variables are changed!!! )
My first big goal is to change chip_count within my structure.
Here the program flow:
I create a pointer to a special type of structure.
I pass this pointers address to a function.
The function creates a new adress with malloc.
The passed pointer gets this new address.
So it points now on the malloc.
Some variable are of the malloc structure are changed.
Return to main
Access the malloc space and read out the changed stuff
Result:
YES IT WORKS
Sry I added some more functions to understand const declarations better.
Pointer stuff:
vtss_state_t is the same as struct vtss_state_s
vtss_inst_t in turn is a pointer on struct vtss_state_s or vtss_state_t
the function vtss_create() has a parameter *vtss_inst_t const inst
This is a pointer on the pointer of of vtss_sate_s or a pointer to vtss_inst_t.
In the function at the end the adress of malloc is passed to (*inst).
(*inst) is the content of the of the pointer on which inst is pointing to.
So the pointer will point to malloc().
I hope this is right...
FIRST APPROACH ONLINE COMPILER
I just wanted to see if I can change values in my passed structure.
Result: YES
FILE:state.h
#include <stdint.h>
/******************************************************************************
Structures
*******************************************************************************/
typedef struct tests
{
int x;
} tests_t;
typedef uint32_t u32;
// This is the structure with chip_count
typedef struct vtss_state_s
{
int a;
int cookie;
tests_t u;
int port_count;
u32 chip_count // doesnt change in my real program :(
} vtss_state_t;
// typedef this structure so vtss_inst_t points to it...(?)
typedef struct vtss_state_s *vtss_inst_t;
FILE: main.c
/******************************************************************************
Online C Compiler.
Code, Compile, Run and Debug C program online.
Write your code in this editor and press "Run" button to compile and execute it.
*******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include "state.h"
#define VTSS_PORT_COUNT 1
#define VTSS_PORTS VTSS_PORT_COUNT
//
// some global structure
vtss_inst_t testspace;
vtss_inst_t *testspace_ptr;
/******************************************************************************
functions
*******************************************************************************/
// vtss_inst_get ()
// const adress another access style
void
vtss_inst_get (const vtss_inst_t inst)
{
printf ("\ninst get()");
printf ("\ninst get() adress of inst:%d", inst);
inst->a = 1111;
}
// This function just should proof that it can change the content
void
vtss_inst_default_set (vtss_state_t * vtss_state)
{
vtss_state->port_count = VTSS_PORTS; // 1
}
//** This is the function which should change "chip_count"
// Man soll einen Pointer auf einen Pointer auf die Struktur C<bergeben (wo sich chip_count befindet )
void
vtss_inst_create (vtss_inst_t * const inst)
{
printf ("\r\n**vtss_inst_create()");
vtss_state_t *vtss_state; // temporary pointer ( just points to a structure )
vtss_state_t *vtss_state_2; // just a test compare
// pass temporary pointer a new memory space:
vtss_state = malloc (sizeof (*vtss_state)); // is this correct? anyway it also doesnt work without this malloc style
printf ("\r\n\t malloc=: %d", vtss_state);
// pass test temporary pointer a new memory space:
vtss_state_2 = malloc (sizeof (*vtss_state_2));
printf ("\r\n\t (test) malloc2: %d", vtss_state_2);
//Test: pass the temporary pointer even deeper & change content of structure where it points to
// (change variable port_count to 1)
vtss_inst_default_set (vtss_state);
vtss_inst_default_set (vtss_state_2);
//Test:Change values of the structure:
vtss_state->a = 1;
vtss_state->chip_count = 12121;
vtss_state_2->chip_count = 12121;
// ** Giving back the new adress from malloc:
// Test:(from vtss_state or vtss_state2)
(*inst) = vtss_state; //passing adress1
//Test: a should have the correct value:
printf ("\r\n\ta=1? a =%d ", (*inst)->a);
(*inst) = vtss_state_2; //passing adress2
// Some extra tests:
(testspace) = vtss_state_2; // extra Test: pass the adress to a test pointer
testspace_ptr = &testspace; // extra Test: pass the adress to a test pointer
(*testspace_ptr) = vtss_state_2; // extra Test: pass the adress to a test pointer
vtss_state_2->a = 22; // extra Test: change content of test pointer
printf ("\r\n\ta=22? a=%d ", (*inst)->a); //
}
/******************************************************************************
main
*******************************************************************************/
int
main ()
{
// **The main structure:
vtss_state_t state_test;
state_test.a = 1234; // pass some test value
// **pointer to type of vtss_state_t
vtss_inst_t inst;
// **pass the adress of the structure!:
inst = &state_test;
// Test: add a value to a structure of the structure:
// (is the same like inst->)
state_test.u.x = 123;
// Test:
inst->chip_count = 888;
vtss_inst_get (inst);
// Test: I declared two global structure to test global access:
printf ("\ntestspace points to: %d", testspace);
printf ("\ntestspace ptr points to: %d", testspace_ptr);
// Test variable a:
printf ("\n1234? inst->a=%d", inst->a);
// Test: show value of structure in a strucure:
printf ("\n123? state_test.u.x=%d", state_test.u.x);
// Test: before & after address is changed:
printf ("\r\n * Before create(): Adress inst:%d", inst);
printf ("\r\n******* Before create():chip_count: %d", inst->chip_count);
vtss_inst_create (&inst);
printf ("\r\n\n * After create(): Adress of inst:%d", inst);
printf ("\r\n\t 22? a:%d", inst->a);
printf
("\r\n even the layer2 function in create() worked:\n port_count=1?: %d",
inst->port_count);
printf
("\r\n\n\n******* chip_count has changes correctly to 12121: %d\n\n\n",
inst->chip_count);
//extra tests with the global structures:
printf ("\ntestspace points to: %d", testspace);
printf ("\n testspace has the correct value a: %d", testspace->a);
printf ("\n testspace_ptr has the correct value a:: %d",
(*testspace_ptr)->a);
printf ("\n adress of pointer testspace_ptr points to?:%d", testspace_ptr);
// extra test:
vtss_inst_get (inst);
printf ("\n there is even access to a:%d", inst->a);
printf ("\nPE-Hello World");
return 0;
}
SECOND APPROACH: ARM CORTEX M3 in VSC:
I just want to change chip_count but the library function doesn't do it!
vtss_rc **vtss_inst_create**(const vtss_inst_create_t *const create, vtss_inst_t *const inst, void (*print)(void))
{
vtss_state_t *vtss_state;
vtss_state = malloc(sizeof(*vtss_state));
vtss_state->chip_count = 777;
(*inst) = vtss_state;
I call it in the main: vtss_inst_create(&create, &inst);
( now I also deleted the third test parameter: I should change it here, but result is anyway same)
when I read chip_count out in the main :
sprintf(t2, "\r\n main: chipcount should be 777 %d ??", (int)(inst->chip_count));
print_uart(t2);
Then it prints:
482531848 !!!!!!
I copied this function:
void createtest2(vtss_inst_t *const inst)
{
vtss_state_t *vtss_state;
vtss_state = malloc(sizeof(*vtss_state));
vtss_state->chip_count = 888;
(*inst) = vtss_state;
}
it is called: createtest2(&inst);
sprintf(t2, "\r\n main: wie in create() chipcount 888?: %d", (int)(inst->chip_count));
print_uart(t2);
it prints 888 correctly i guess because it prints it ..
I copied it also with correct header:
vtss_rc vtss_inst_create3(const vtss_inst_create_t *const create, vtss_inst_t *const inst, void (*print)(void))
{
vtss_state_t *vtss_state;
vtss_state = malloc(sizeof(*vtss_state));
vtss_state->chip_count = 222;
(*inst) = vtss_state;
(void)create;
(void)print;
return 1;
}
I call it: vtss_inst_create3(&create, &inst, spitest);
(ignore please the third parameter)
it prints out 222 correctly
How is that possible?
Or is this simply magic :)
Update: I checked it and it is shocking to me.
lol
it works in every kind of function but not with that one I want to do it xD
First I just copied the function but only one parameter. It worked.
Then I copied it with all parameters. It worked.
But the original library func. doesn't work.
In the past I changed the library function a little bit:
Ok in the past a tuned the library function by adding one little parameter as a little test.
In combination, that it is a library function in not located in the same file it may cause some trouble.
I will now change the header back to normal:
Normal:
vtss_rc vtss_inst_create(const vtss_inst_create_t *const create,
vtss_inst_t *const inst)
How i tuned it:
vtss_rc vtss_inst_create(const vtss_inst_create_t *const create, vtss_inst_t *const inst, void (*print)(void))
{
update: lol I rechanged the function it back to normal.
Hmmm....
Another file?
Then it must be because the function is in another file or what.
I checked inside the functions they point to the same addresses as outside (main).. I mean the value of inst.
Todo I print out now the addresses of chip_count
Update: OMG something is wrong with the compiler. I compared it as described with similar functions.
Same function different result of chip_count.
But another variabale e.g. "cookie" can be changed!
So one variable is change another not.
This was really confusing to me because I didn't expect it!
CMAKE:
Maybe there is an error which is suppressed by my CMAKE. So the compiler ignores the error. At runtime the error comes to light.
add_target_compile_flags(base PRIVATE "" "-Wno-unused-parameter" "-Wno-pedantic" "-Wno-format" "-Wno-sign-conversion" "-Wno-switch-default" "-Wno-conversion" "-Wno-unused-variable" "-Wno-undef" "-Wno-unused-but-set-variable" "-Wno-unused-function" "-Wno-implicit-function-declaration" "-Wno-uninitialized")

How can I configure flow.js to use comments when my eslint adds spacing in my function arguments?

My function is:
getConferenceNumberAndPin: (description = null /*: string */ , entryPoints = null /*: Array<object> */ ) => {
As you can see, it adds a space before the comma: */ , as well as one before the ).
I am using --fix with eslint, so the spacing is automatically added. But now flowjs complains:
Unexpected token ,, expected the token )
How can I get the 2 to play nicely?
I think the issue with the code is the placement of the type comments. Function parameters with defaults shows an example function declaration
function method(value: string = "default") { /* ... */ }
Notice that the type comes before the default value. Therefore, in your example, your function declaration would look like
function getConferenceNumberAndPin(
description: ?string = null,
entrypoints: ?Array<Object> = null
) { /* ... /* }
And, using the comment syntax (shortened the function name so it can be written on one line)
function f(description /*: ?string */ = null, entrypoints /*: ?Array<Object> */ = null): void {}
The spacing before and after the commas and parentheses should not matter. You can play around with your example at Try Flow to experiment with the spacing that eslint would insert.

Cannot pass immutable value as inout argument: function call returns immutable value

I forked this project, so I am not as familiar with all of the details: https://github.com/nebs/hello-bluetooth/blob/master/HelloBluetooth/NSData%2BInt8.swift.
This is all part of an extension of NSData that the I am using to send 8-bit values to an Arduino.
func int8Value() -> Int8 {
var value: Int8 = 0
copyBytes(to: &UInt8(value), count: MemoryLayout<Int8>.size) //BUG
return value
}
However, it appears in Swift 3 that this now throws an error in the copyBytes section. Although I have seen some solutions such as passing an address in the parameter, I did not want to risk breaking the remaining parts of the code. Any suggestions on what to do for this?
The original code was incorrect. UInt8(value) generates a new, immutable value which you cannot write to. I assume the old compiler just let you get away with it, but it was never correct.
What they meant to do was to write to the expected type, and then convert the type at the end.
extension Data {
func int8Value() -> Int8 {
var value: UInt8 = 0
copyBytes(to: &value, count: MemoryLayout<UInt8>.size)
return Int8(value)
}
}
That said, I wouldn't do it that way today. Data will coerce its values to whatever type you want automatically, so this way is safer and simpler and very general:
extension Data {
func int8ValueOfFirstByte() -> Int8 {
return withUnsafeBytes{ return $0.pointee }
}
}
Or this way, which is specific to ints (and even simpler):
extension Data {
func int8Value() -> Int8 {
return Int8(bitPattern: self[0])
}
}

Why isn't python-exposed boost::gregorian::date available everywhere?

I exposed boost::gregorian::date with the following:
date_from_python_date{};
to_python_converter<date, date_to_python_date, true>{};
where date_to_python_date is a struct with the right convert function: it converts it to a python datetime.date.
Some c++ functions return date and calling them from python works.
At a later stage, I have a c++ class
class F {
/// ....
public:
boost::gregorian::date start;
};
which I register with:
class_<F, F*, bases<B>>("F")
.def_readwrite("start", &F::start, "FTD")
;
I do this after having python-registered date.
I then obtain an instance f of the F wrapper. But then, when I print
f.start
The error is:
No Python class registered for C++ class boost::gregorian::date
In short, the return policy used by def_readonly() and def_readwrite() will default to using return_internal_reference for user-defined class types (see make_getter()). This return policy will suppress the use of custom converters. To resolve this, replace def_readonly() and def_readwrite() with add_property(), providing a boost::python::return_value_policy with a type of boost::python::return_by_value.
Change:
namespace python = boost::python;
python::class_<F, F*, python::bases<B>>("F")
.def_readwrite("start", &F::start, "FTD")
;
to:
namespace python = boost::python;
python::class_<F, F*, python::bases<B>>("F")
.add_property("start",
python::make_getter(
&F::start, python::return_value_policy<python::return_by_value>()),
python::make_setter(
&F::start, python::return_value_policy<python::return_by_value>()),
"FTD")
;
Here is a complete example demonstrating this difference:
#include <boost/python.hpp>
/// Mocks...
// Mockup user defined type.
class spam {};
struct egg
{
spam spam;
};
// Mockup convert that converts spam into 'hello world' strings.
struct spam_converter
{
static PyObject* convert(const spam&)
{
namespace python = boost::python;
python::str result("hello world");
return python::incref(result.ptr());
}
};
BOOST_PYTHON_MODULE(example)
{
namespace python = boost::python;
// Enable spam to string converter.
python::to_python_converter<spam, spam_converter>();
// Expose egg.
python::class_<egg>("Egg")
// Expose egg::spam as spam1, access will fail to find converter.
.def_readonly("spam1", &egg::spam)
// Expose egg::spam as spam2, automatic conveter will be found.
.add_property("spam2",
python::make_getter(
&egg::spam, python::return_value_policy<python::return_by_value>()))
;
}
Interactive usage:
>>> import example
>>> egg = example.Egg()
>>> try:
... spam = egg.spam1 # expect to throw
... assert(False)
... except TypeError:
... assert(True)
...
>>> spam = egg.spam2
>>> assert(spam == "hello world")
Note that although the same egg::spam data-member instance was being exposed as Egg.spam1 and Egg.spam2, the manner in which the data-member was being exposed affected whether or not the automatic converter was found during dispatch.

Golang : type conversion between slices of structs

This questions follows another question of mine.
I don't exactly get what is wrong with my attempt to convert res to a ListSociete in the following test code :
import (
"errors"
"fmt"
"github.com/jmcvetta/neoism"
)
type Societe struct {
Name string
}
type ListSociete []Societe
func loadListSociete(name string) (ListSociete, error) {
db, err := neoism.Connect("http://localhost:7474/db/data")
if err != nil {
return nil, err
}
res := []struct {
Name string `json:"a.name"`
}{}
cq := neoism.CypherQuery{
Statement: `
MATCH (a:Societe)
WHERE a.name = {name}
RETURN a.name
`,
Parameters: neoism.Props{"name": name},
Result: &res,
}
db.Cypher(&cq)
if len(res) == 0 {
return nil, errors.New("Page duz not exists")
}
r := res[0]
return ListSociete(res), nil
}
Is a []struct{Name string} different from a []struct{Name string json:"a.name" } ?
Or is a ListSociete different from a []struct{Name string} ?
Thanks.
You are currently dealing with two different types:
type Societe struct {
Name string
}
and the anonymous one:
struct {
Name string `json:"a.name"`
}
These two would be identical if it wasn't for the tag. The Go Specifications states (my emphasis):
Two struct types are identical if they have the same sequence of fields, and if
corresponding fields have the same names, and identical types, and identical tags.
Two anonymous fields are considered to have the same name. Lower-case field names
from different packages are always different.
So, you can't do a simple conversion between the two. Also, the fact that you are converting slices of the two types makes the conversion problematic. I can see two options for you:
Copy through iteration:
This is the safe and recommended solution, but it is also more verbose and slow.
ls := make(ListSociete, len(res))
for i := 0; i < len(res); i++ {
ls[i].Name = res[i].Name
}
return ls, nil
Unsafe conversion:
Since both types have the same underlying data structure, it is possible to do an unsafe conversion.
This might however blow up in your face later on. Be warned!
return *(*ListSociete)(unsafe.Pointer(&res)), nil
Playground Example: http://play.golang.org/p/lfk7qBp2Gb
So, after some tests, here's whats i found out :
A ListSociete defined as such...
type Societe struct {
Name string `json:"a.name"`
}
type ListSociete []Societe
is different from this :
type ListSociete []struct {
Name string `json:"a.name"`
}
This second solution works, whereas the first doesn't.
So I assume there really is no way to convert (directly without writing an explicit loop) between types with different tags ?
In that case, i'll definitely go with the loop, as using tags directly in types (cf. second solution above) would make my code unreadable and unreusable, also I really have no clue what I would be messing with using the unsafe conversion method. So thanks for confirming different tags made different types.

Resources