Get the name of a coll object in Max C API - c

I am writing a Max MSP external.
I am lost in Max C API documentation since hours and couldn't find a way to get the name of a coll object from Max C API.
https://cycling74.com/sdk/max-sdk-8.0.3/html/index.html
If the object is | coll foo | , foo is the symbol I want to get.
I am able to iterate over a patcher and get pointers to all boxes and then to objects by calling jbox_get_object() with pointers to boxes. I tried getting many attributes of the objects I got and everything works ok.
I can't seem to find where the data I want to get is stored and what is it called.
I would appreciate some help.
Thank you.

[coll] is very sparsely documented, you should ask on the Cycling74 dev-forum. Below is what I do in [posit] after traversing the patcher to find a coll’s box. hth /*j
#include “coll.h”
<snip>
t_object *o;
t_coll *collob;
t_object *jb;
t_symbol *collname;
<snip>
o = jbox_get_object(jb);
collob = (t_coll *)o;
collname = (t_symbol *)collob->c_x->c_sym;
</snip>

Thank you user12106422! This is how I have implemented this in my iterator function and it works perfectly.
#include "coll.h"
//in your iterator function ..
long patcher_iterator(<replace this with your external type> *x, t_object *b) {
//check if object is a coll
if(strncmp(object_classname( jbox_get_object(b) )->s_name, "coll",4) == 0){
t_coll *collobject;
t_symbol *collname;
collob = (t_coll *)jbox_get_object(b);
collname = (t_symbol *)collobject->c_x->c_sym;
post("--The name of the coll is (%s) ", collname->s_name);
}
}
I would also like to share coll.h here for common benefit.
/* -------- coll.c -- the collection object --------------- */
#include "ext.h"
// #include "edit.h"
#include "ext_wind.h"
#include "ext_common.h"
#include "ext_strings.h"
#include "ext_critical.h"
#define C_EMBED 1
/* ddz 06/09/94:
* fixed interspersed (entremele) use of next and prev messages
* added assistance for third outlet
* prototyped functions and removed voids
* fixed truncating on sorts
*/
/* sde use to fill the read and write flags */
#define FILE_DIALOG 1 /* use dialogs to get file name */
#define FILE_NAMED 2 /* symbol specifies file name */
#define Index_Integer 1
#define Index_Symbol 2
typedef struct celem { /* doubly linked list element */
short e_size;
short e_extra;
long e_index;
t_symbol *e_assoc;
struct celem *e_next;
struct celem *e_prev;
t_atom e_data[1]; /* dummy */
} t_celem;
typedef struct xcoll {
t_object c_ob;
void *c_data; // linklist
//t_celem c_head; /* head of list elements */
t_celem *c_next; /* element to be returned by "next" */
t_celem *c_prev; /* element to be returned by "prev" */
void *c_out2; /* next "end" signal outlet */
char c_read,c_write; /* flags for reading & writing */
char c_freeing,c_saveme;
char c_embed; /* embed in owning patcher? */
t_symbol *c_sym; /* associated symbol? */
struct ed *c_edit; /* edit window */
short c_refcount; /* reference count */
struct coll *c_refcoll; /* list of "colls" that reference this xcoll */
/* sde filename, volume, and MAX type */
t_symbol *c_fn;
short c_vol;
short c_bin;
long c_type; /* type of the file that was read in */
short c_modified;
long c_filetype; /* for filetype message -- allowed types */
long c_modcount;
} t_xcoll;
typedef struct coll {
t_object c_ob;
t_xcoll *c_x;
t_symbol *c_sym;
void *c_out2;
/* sde third outlet bangs after reading data */
void *c_out3;
void *c_out4;
struct coll *c_nextref; /* next in the list of colls that share this coll's xcoll */
void *c_owner;
long c_nosearch;
} t_coll;

Related

'cannot convert from...' error during callback assignations (migrated code from C)

I'm migrating some lines coded on C to C++/CLI (UI Windows Form based on .NET). One of my problems comes when I try to do this kind of assignation:
myCallbacks.cbf_data_write = this->dataWriteFunc;
In this case, dataWriteFunc is defined as:
PNIO_IOXS dataWriteFunc(PNIO_UINT32, PNIO_DEV_ADDR *, PNIO_UINT32, PNIO_UINT8 *, PNIO_IOXS);
And myCallbacks is declared as
PNIOD_CBF_FUNCTIONS myCallbacks;
with
typedef struct {
PNIO_UINT32 size; /* size of struct = sizeof(PNIO_CBF_FUNCTIONS) */
PNIO_CBF_DATA_WRITE cbf_data_write; /* mandatory */
PNIO_CBF_DATA_READ cbf_data_read; /* mandatory */
PNIOD_CBF_ASYNC_REC_READ cbf_async_rec_read; /* mandatory */
PNIOD_CBF_ASYNC_REC_WRITE cbf_async_rec_write; /* mandatory */
PNIOD_CBF_SYNC_ALARM_DONE cbf_sync_alarm_done; /* mandatory */
PNIOD_CBF_ASYNC_CONNECT_IND cbf_async_connect_ind; /* mandatory */
PNIOD_CBF_ASYNC_OWNERSHIP_IND cbf_async_ownership_ind; /* mandatory */
PNIOD_CBF_ASYNC_INDATA_IND cbf_async_indata_ind; /* mandatory */
PNIOD_CBF_SYNC_DISCONNECT_IND cbf_sync_disconnect_ind; /* mandatory */
PNIOD_CBF_SYNC_DATA_STATUS_IND cbf_sync_data_status_ind; /* mandatory */
PNIOD_CBF_ASYNC_PRM_END_IND cbf_async_prm_end_ind; /* mandatory */
PNIOD_CBF_SYNC_STOPPED cbf_sync_device_stopped; /* mandatory */
PNIOD_CBF_ASYNC_IRT_INIT_INPUTS cbf_async_irt_init_inputs; /* mandatory for IRT top */
PNIOD_CBF_SYNC_CP_STOP_REQ cbf_sync_cp_stop_req; /* optional */
PNIOD_CBF_SYNC_START_LED_FLASH cbf_sync_start_led_flash; /* optional */
PNIOD_CBF_SYNC_STOP_LED_FLASH cbf_sync_stop_led_flash; /* optional */
PNIOD_CBF_RESERVED
} ATTR_PACKED PNIOD_CBF_FUNCTIONS;
Also:
typedef PNIO_IOXS (*PNIO_CBF_DATA_WRITE) /* write data to IO stack (local ==> remote) */
(PNIO_UINT32 DevHndl, /* Handle for Multidevice */
PNIO_DEV_ADDR * pAddr, /* geographical address */
PNIO_UINT32 BufLen, /* length of the submodule input data */
PNIO_UINT8 * pBuffer, /* Ptr to data buffer to write to */
PNIO_IOXS Iocs); /* remote (io controller) consumer status */
So, what exactly I'm doing wrong? VS2012 gives me next error:
Error 4 error C2440: '=' : cannot convert from 'PNIO_IOXS (__thiscall CP1626::* )(PNIO_UINT32,PNIO_DEV_ADDR *,PNIO_UINT32,PNIO_UINT8 *,PNIO_IOXS)' to 'PNIO_CBF_DATA_WRITE' c:\users\hp\documents\visual studio 2012\projects\ui_cp1626\ui_cp1626\Profinet_IDevice.h 513 1 UI_CP1626
What's the correct form to associate callbacks in this case?
Thank you in advance.
You're trying to convert thiscall function (non-static class member function) to ordinary function. The problem is non-static class members take extra implicit argument, the pointer to class object aka this, so dataWriteFunc's implicit signature is:
PNIO_IOXS dataWriteFunc(CP1626 *this, PNIO_UINT32, PNIO_DEV_ADDR *,
PNIO_UINT32, PNIO_UINT8 *, PNIO_IOXS);
, note the 1st argument, it's implicit presence is what gives function "__thiscall" attribute. If you declare this function as
static PNIO_IOXS dataWriteFunc(PNIO_UINT32, PNIO_DEV_ADDR *,
PNIO_UINT32, PNIO_UINT8 *, PNIO_IOXS);
then the error will go away. Note that inside static methods this is not available.

How implement PostgreSQL extension using PostGIS types

I would like to create a new data type for PostGIS, but I have some difficulties. Here's what I've done so far:
/* PostgreSQL */
#include <postgres.h>
#include <liblwgeom.h>
#include <lwgeom_pg.h>
#include <utils/timestamp.h>
struct trajectory_elem
{
// int32 dummy; /* Padding to make it double aligned. */
Timestamp time_obj;
LWGEOM *geom_elem; /* Geometry Object - */
};
#define DatumGetTrajectoryElem(X) ((struct trajectory_elem*) PG_DETOAST_DATUM(X))
#define PG_GETARG_TRAJECTELEM_TYPE_P(n) DatumGetTrajectoryElem(PG_GETARG_DATUM(n))
#define PG_RETURN_TRAJECTELEM_TYPE_P(x) PG_RETURN_POINTER(x)
extern Datum create_trajectory_elem(PG_FUNCTION_ARGS);
extern Datum trajectory_elem_in(PG_FUNCTION_ARGS);
extern Datum trajectory_elem_out(PG_FUNCTION_ARGS);
.....
PG_FUNCTION_INFO_V1(create_trajectory_elem);
Datum
create_trajectory_elem(PG_FUNCTION_ARGS)
{
Timestamp time_geom = PG_GETARG_TIMESTAMP(0);
GSERIALIZED *geom = (GSERIALIZED*)PG_DETOAST_DATUM(PG_GETARG_DATUM(1));
struct trajectory_elem *trje = (struct trajectory_elem *) palloc(sizeof(struct trajectory_elem));
trje->time_obj = time_geom;
/*get lwgeom from GSERIALIZED varlena*/
trje->geom_elem = lwgeom_from_gserialized(geom);
if ( lwgeom_is_empty(trje->geom_elem))
{
PG_FREE_IF_COPY(geom, 0);
PG_RETURN_NULL();
}
PG_FREE_IF_COPY(geom, 0);
PG_RETURN_TRAJECTELEM_TYPE_P(trje);
}
Is the way I'm creating my trajectory_elem structure correct?
Can I simply point to the LWGEO type? Or.. Should I create a new type like the GSERIALIZED ?
How would the input and output functions for this type be? Could I use the functions already implemented by PostGIS?
I tested some implementations for the I / O functions but when it arrives in PG_RETURN_TRAJECTELEM_TYPE_P (create_trajectory_elem), the server drops. So they were probably wrong

Change Struct module pointer

Good day all, I'd like some help to change a small section in this C program which I have licensed back in the early 90's. Some of you may be familiar with it, it's called MajorBBS and as you probably have guess it is bbs software.
In the header file majorbbs.h we have
extern
struct module { /* module interface block */
char descrp[MNMSIZ]; /* description for main menu */
int (*lonrou)(); /* user logon supplemental routine */
int (*sttrou)(); /* input routine if selected */
void (*stsrou)(); /* status-input routine if selected */
int (*injrou)(); /* "injoth" routine for this module */
int (*lofrou)(); /* user logoff supplemental routine */
void (*huprou)(); /* hangup (lost carrier) routine */
void (*mcurou)(); /* midnight cleanup routine */
void (*dlarou)(); /* delete-account routine */
void (*finrou)(); /* finish-up (sys shutdown) routine */
} **module;
Also in the majorbbs.h we have some code that defines the menu variables
extern
struct usrmnu { /* user's menuing-specific variables */
char curpag[PNMSIZ]; /* current menu page */
char parpag[PNMSIZ]; /* parent menu page */
char selchrs[MAXSEL]; /* select characters currently available */
char pages[MAXSEL][PNMSIZ]; /* pages or file names for select chars */
char optdsp[MAXSEL]; /* instructions on how to display options */
int keyreq[MAXSEL]; /* key required for each select character */
FILE *fp; /* pointer to file currently being viewed */
char mnuttl[TITLSZ]; /* menu page title */
} *mnuusr;
Then in the majorbbs.c file we have
struct module module00={ /* module interface block */
"Menuing System", /* description for main menu */
NULL, /* user logon supplemental routine */
mainu, /* input routine if selected */
musthn, /* status-input routine if selected */
NULL, /* "injoth" routine for this module */
NULL, /* user logoff supplemental routine */
loscar, /* hangup (lost carrier) routine */
midnit, /* midnight cleanup routine */
NULL, /* delete-account routine */
mjrfin /* finish-up (sys shutdown) routine */
};
What I'd like is to change the value of the descrp here which is defined as "Menuing System" to something more dynamic like the Menu the user is currently on.
From the code here I think it would be mnuusr->curpag which is where the pointer is pointing to I think.
So I'm thinking of a routine. I am by no means a programmer and I've been there many sites to look for examples of how to do such a thing. I've searched here for the last couple days (before posting this). I saw some things
that sparked a "Hey this might work" but I ended up with compiler errors (more on that in a bit)
What I did was make a routine like
char *
mydescrp
{
if (strcmp(module00.descrp,"Menuing System" ) == 0 ) {
mnuusr=mnuoff(usrnum);
return(mnuusr->mnuttl);
}
}
Then if I change the module00 call above to
struct module module00={
mydescrp, /* My change */
NULL,
mainu,
musthn,
NULL,
NULL,
loscar,
midnit,
NULL,
mjrfin
};
When I compile I get some error that says:
Initalization not fully bracketed
the list goes on from there. There are some further initialization later on in majorbbs.c and will gladly supply them if you need. I am sure one would be.
int
register_module( /* register a module for online use */
struct module *mod) /* pointer to a module block */
{
if (strlen(mod->descrp) > MNMSIZ-1) {
catastro("MODULE NAME \"%s\" TOO LONG!",mod->descrp);
}
if (mod->stsrou == NULL) {
mod->stsrou=dfsthn;
}
if (nmods == 0) {
module=(struct module **)alcmem(sizeof(struct module *));
mdstats=(struct mdstats *)alcmem(sizeof(struct mdstats));
}
else {
module=(struct module **)alcrsz(module,sizeof(struct module *)*nmods,
sizeof(struct module *)*(nmods+1));
mdstats=(struct mdstats *)alcrsz(mdstats,sizeof(struct mdstats)*nmods,
sizeof(struct mdstats)*(nmods+1));
}
module[nmods]=mod;
setbtv(mstbb);
if (qeqbtv(mod->descrp,0)) {
gcrbtv(&mdstats[nmods],0);
}
else {
setmem(&mdstats[nmods],sizeof(struct mdstats),0);
strcpy(mdstats[nmods].mdname,mod->descrp);
}
rstbtv();
return(nmods++);
}
From MENUING.C mnuoff routine
struct usrmnu *
mnuoff( /* get pointer to user's menu info */
int unum) /* user number to grab */
{
#ifdef PHARLAP
return((struct usrmnu *)((long)(eclmnubas+(unum<<3))<<16));
#else
#ifdef ECLIPSE
return((struct usrmnu *)((long)(eclmnubas+(unum<<3))<<16));
#else
return((struct usrmnu *)(muusrs+(unum*(long)sizeof(struct usrmnu))));
#endif
#endif
}
Is this the routine to change for some newly code? I am simply at a loss on how to go about this. If you need more code let me know.
I even went as far as asking for help from other majorbbs programmers on usenet but this software is 20 years + old so I don't think anyone uses it anymore let alone modify code anymore. I would think since it's still C someone might have an idea to help me out. I am trying to create a new revive with some small modifications. This being one of two.
Thanks for any help.
It looks like the descrp field in struct module is expecting a char[] (or a string), and you're giving it a char *() (function returning a string) instead.
Perhaps what you want to do is not call the mydescrp function in the declaration of module00, but manually perform the check in register_module:
int register_module(struct module *mod) {
if (strcmp(mod->descrp, "Menuing System") == 0) {
struct usrmnu *menu = mnuoff(usrnum);
// Copy as much of the title to the menu description as possible.
strncpy(mod->descrp, menu->mnuttl, MNMSIZ-1);
// Terminate the string in case the title was too long.
mod->descrp[MNMSIZ-1] = '\0';
}
// Rest of method.
}

Confusion on sqlite3 struct in sqlite3 source code

In the function
static int sqlite3Prepare(
sqlite3 *db, /* Database handle. */
const char *zSql, /* UTF-8 encoded SQL statement. */
int nBytes, /* Length of zSql in bytes. */
int saveSqlFlag, /* True to copy SQL text into the sqlite3_stmt */
Vdbe *pReprepare, /* VM being reprepared */
sqlite3_stmt **ppStmt, /* OUT: A pointer to the prepared statement */
const char **pzTail /* OUT: End of parsed string */
) {
...
pParse = sqlite3StackAllocZero(db, sizeof(*pParse));
...
assert( !db->mallocFailed );
...
}
I know sqlite3 is just a fake struct declared as
typedef struct sqlite3 sqlite3;
without any body. I know sqlite3 * is usually is cast to a Vdbe*.
But here, db is of the type of sqlite3*, how can db->malloFailed exist? Why doesn't the compiler complain?
There is similar situation with sqlite3_stmt:
typedef struct sqlite3_stmt sqlite3_stmt;
with no body. I guess sqlite3_stmt is a syntax tree of parsed SQL statements. I would like to see the structure of it. However, the type is hidden so deeply using this weird pattern that I can't see what it is.
Even Vdbe is the same situation...
typedef struct Vdbe Vdbe;
Where on earth is the real struct?
sqlite3 is not a fake struct; the sqlite.h file just does not define its body.
Its definition is in the sqliteInt.h file (which is also part of the sqlite3.c amalgamation):
/*
** Each database connection is an instance of the following structure.
*/
struct sqlite3 {
sqlite3_vfs *pVfs; /* OS Interface */
struct Vdbe *pVdbe; /* List of active virtual machines */
CollSeq *pDfltColl; /* The default collating sequence (BINARY) */
...
u8 mallocFailed; /* True if we have seen a malloc failure */
...

Compiler Error in C: expected ')' before '*' token

As the title says, keep getting this error when trying to compile. From Googling this error people have said that it is not declared in the header file but my function is static and it is not in a header file, I prototyped it.`
#include <recGbl.h>
#include <devSup.h>
#include <devLib.h>
#include <drvIpac.h>
#include <dbScan.h>
#include <epicsExport.h>
static int cardinit(cardinfo *card); // <-- line that gives the error
typedef struct cardinfo{
struct cardinfo *next;
struct io_mem_read *pMem; /* IP register (A16) mem address */
word *rambase; /* RAM conversion memory mem address*/
int isconfigured;
int doram; /* 1 if we are using the RAM to output data.
0 if we are writing to registers (AO style) */
int cardnum;
int vmeslotnum;
int ipslotnum;
/* these values mirror the hardware registers */
word csr;
word offset;
word numconv;
word clockrate;
word vectnum;
word dacval[MAXSIGNAL];
word oldispresent;
/* used to detect a reinsertion of a carrier card.
see subroutine ispresent() below. */
/* use to update process variables */
IOSCANPVT ioscanpvt;
} cardinfo;
static int Hy8402init(int vmeslot, int ipslot, int clockrate) {
cardinfo *card;
card->vmeslotnum = vmeslot;
card->ipslotnum = ipslot;
card->cardnum = 1;
card->clockrate = clockrate;
card->vectnum = 10;
cardinit(card);
return TRUE;
}
static int cardinit(cardinfo *card){
word rprobe;
int res;
volatile word *ramptr;
card->pMem= ipmBaseAddr(card->vmeslotnum,
card->ipslotnum,ipac_addrIO);
if (card->pMem==NULL){
printf("Error in %s",devstr);
printf( "%s: Cannot determine base address\n",devstr);
return FALSE;
}
res=devReadProbe(sizeof (word),(char *) card->pMem,(char *) &rprobe);
if (res!=OK){
printf("%s: NO DEVICE at %x (vmeslot %d, ipslot %d)\n",devstr,
(int)card->pMem,
card->vmeslotnum,card->ipslotnum);
return FALSE;
}
return TRUE;
}
`
cardinfo struct is still undefined on the line with error. Put a forward declaration before it:
struct cardinfo;
static int cardinit(struct cardinfo *card);
This line of code:
static int cardinit(cardinfo *card);
should be added after the definition of your cardinfo structure.
You need to put the line
static int cardinit(cardinfo *card);
after the definition of the cardinfo structure.
At that line, the compiler doesn't yet know that cardinfo is a struct. Precede it with the line struct cardinfo;
You have declared a function which has a input variable of a type which the compiler is not aware when it parses it. i.e the struct defintion follows your function declaration.
So please do a forward declaration of the structure when you want to compile such code.
In computer programming, a forward declaration is a declaration
of an identifier (denoting an entity such as a type, a variable, or a
function) for which the programmer has not yet given a complete definition.
This link has a nice article on when full declarations are not required.

Resources