Plugins and standard C, first steps?

Hi.
I’m trying to do, the first time, a plugin to have the basic functionality of a neural network. To do the NN I use the genann code (simple code and I think smart, github https://github.com/codeplea/genann) that is written in C standard.

My doubts … How can I manage the standard functions in the plugin, for example I/O and file pointers?, how can I manage the standard C memory?, how can I access members of a structure written by my? My knowledge of C are basic/intermediate (somewhat rusty) but I think enough to embark on this project. Any clues or suggestions?

Thank you very much.

Look at the Examples - but for current Xojo they are a littlebit outdated and for Linux you must change some compiler settings (search the forum for it)

Depends on platform
The most recent Windows guide is likely Program Plugins with Xojo in Windows Version 2.0

And I put this together for OS X but it doesn’t answer a bunch of your questions http://great-white-software.com/miscellaneous/Plugins%20Getting%20started.pdf

Thanks for the answers, friends …
I bought Eugene’s books and they’re fine. In fact, I think the best thing is that before constructing the plugin, I will make a DLL and use “declares” to access their functions.

My first attempts were successful (I was able to create the DLL and I could access a couple of simple functions)…
However, when trying to access more complex elements (for example, pointers to structures, or FILE *), I got lost and not in a correct way, for example…

My sampleheader.h

[code]typedef double (*genann_actfun) (double a);

typedef struct genann {
int inputs, hidden_layers, hidden, outputs;
genann_actfun activation_hidden;
genann_actfun activation_output;
int total_weights;
int total_neurons;
double *weight;
double *output;
double *delta;
} genann;

extern __declspec(dllexport) int32_t DoubleValue(int32_t x); //dummy test…
extern __declspec(dllexport) const char *genann_version(void);
extern __declspec(dllexport) genann *genann_init(int inputs, int hidden_layers, int hidden, int outputs);
extern __declspec(dllexport) genann *genann_read(FILE *in);
extern __declspec(dllexport) void genann_randomize(genann *ann);[/code]

My sample.c

#include “dllmain.h”

#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <assert.h>
#include <stdio.h>

[code]int32_t DoubleValue(int32_t x)
{
return 2 * x;
}

const char *genann_version(void)
{
return “0.0.1 20170207”;
}

genann *genann_init(int inputs, int hidden_layers, int hidden, int outputs)
{
return NULL; //pseudo-mock
}

genann *genann_read(FILE *in)
{
return NULL; //pseudo-mock
}

void genann_randomize(genann *ann)
{
//manage *ann…
}

[/code]

My problems appear with the management of pointers to the structure, and FILE*
how do I call them from Xojo?

I’m not sure if I understood your question correctly.
You want to pass a pointer to your genann_read function - ie. maybe a FILE, which was chosen in Xojo?
In this case I highly advise either to read the book or the examples in the PLUGIN-directory.

REAL/Xojo uses his own datatypes and you have to cast them to the c-format (either by one of those Xojo-functions) or by your own routines.
For this case you should write a REAL/Xojo-plugin, which will work as an interface to communicate with your DLL.

GD

I don’t think you need to make a Xojo plugin out of your C code. Plugins are mainly useful so that other users who are not familiar with your C code can easily use it, by adding classes and methods to Xojo’s global set of classes and methods.

Instead, all you probably need to do is make a (dynamic) library, the same way you’d make it so that it can be used with other C programs, and then use “declare” statements to access its functions.

And to answer your question: In general, your C code can simply use all the standard low level functions for i/o, memory, etc, as it would do in a normal C program. It does not clash with Xojo’s functions.

If you have a struct in C and want to access it in Xojo, you’d make a function in C that returns a pointer to it, and in Xojo you’d declare a matching method that returns a “Ptr”. That you can, in Xojo, then assign to a MemoryBlock, and then you can access all the items inside the C structure using the MemoryBlock accessors.

Thank you very much for all your contributions …

Very interesting this note. Thanks you very much, Thomas.

Hi all,

Finally I can access various functions of the DLL made with standard c. My question is now if I need to use MemoryBlock better to store my data reading in a strucutura Xojo … how could I do this (if it is correct to do it, of course)?

[code]Soft Declare Function test_version Lib “genann.dll” As CString
Soft Declare Function test_read Lib “genann.dll” (file As Ptr) As Ptr
Soft Declare Function test_open Lib “genann.dll” (name As CString) As Ptr
Soft Declare Function test_write Lib “genann.dll” (name As CString) As Ptr
Soft Declare Function test_close Lib “genann.dll” (file as Ptr) As Int32

Label1.Text = test_version()
Dim p As Ptr = test_open(“C:\XOJO\FastMath\data.txt”)
Dim q As Ptr = test_read§

//------------------------------------------------
Dim g As testStruct = q.testStruct //<— Is it correct or do I have to use a MemoryBlock ???
//------------------------------------------------

TextArea1.Text = Str(g.x) + “-” + Str(g.y) + “-” + Str(g.z)

Dim clos as Integer
clos = test_close§[/code]

The “data.txt” file contains three rows with integers (x, y, z) and my struct in Xojo is:

x as Integer y as integer z as integer delta as Ptr

Why do you have to ask if that is correct? Can’t you try it out? Generally, both memblk and struct should work.

Oh, wait. Does the file contain text, not binary values? I.e if you view the file with Notepad, you see the numbers in there? Then, of course. you need to read the data into a string, in order to extract the values from it. The same as you would do when reading with a TextInputStream.

Since you cannot transfer ownership of a malloc’d block from C to Xojo, you would have to change your api: You would reserve a memblk in xojo, e.g. as “dim mb as new memoryblock(1024)”, then pass mb and mb.Size to your read function as args (bufPtr as Ptr, bufSite as integer). The C funtion would take them as a char* and an int. It would call the system’s read funtion similarly, and return the actually read amount back to xojo. in xojo code, you can then e tract the string like this:

dim amount as integer = test_read (mb, mb.size)
dim s as string = mb.stringvalue(0, amount)

then you can parse the string for the values in it.

damn, typing on annipad sucks!

Despite annipad … I understood you! :smiley: … thank you!

P.S. Yes, the file has text.