Struct in file.c

BlitzMax Forums/BlitzMax Programming/Struct in file.c

Gavin Beard(Posted 2007) [#1]
Hi all

I have created a c file with some functions and structs in it, i kinda sorted using a function from the c file but how can i use one of the structs from the c file within max, if at all possible?


Chris C(Posted 2007) [#2]
its possible, but unfortunately (as I keep on banging on) its a right royal pain.

basically return a pointer to the struct and then in max you have to use manual offsets to the structs members.

I can show you an example if you want to post a simple example with a struct you want to use.


Gavin Beard(Posted 2007) [#3]
Is it any easier to use a class in a c++ file?

essentially i'm just kinda playing at the moment so its not 100% essential, but i have a struct.c file with :
struct SPlayer{
	int PlayerScore;
	int PlayerID;
	int PlayerHealth;
	int X;
	int Y;
	int Z;
};

then in main.bmx i import the struct.c file wanted to be able to be able to something simple like:
Player1:SPlayer;
Player1.PlayerScore = 10;

but guessing its not so easy


grable(Posted 2007) [#4]
Is it any easier to use a class in a c++ file?

I think with C++ classes you only have access to its virtual methods.

To be able to use memory allocated in C via a BlitzMax Type, you need to do some trickery. And you cant use all BlitzMax types, such as Strings/Objects/Arrays etc.

And this may brake if there are changes to the way BlitzMax handles types.

This is just one way of doing it, there are probably more.

test.bmx:
Import "test.c"

Extern "C"
	Type TStruct
		Field I:Int
		Field F:Float
		Field S:Byte Ptr
	EndType
	
	Function CreateStruct( struct:TStruct Var, i:Int, f:Float, s$z)
	Function CreateStruct2:TStruct( i:Int, f:Float, s$z)
	Function FreeStruct( struct:TStruct Var)
EndExtern

'Local struct:TStruct = CreateStruct2( 10, 1.5, "Hello World!")
Local struct:TStruct
CreateStruct( struct, 10, 1.5, "Hello World!")
Print "ptr: " + Int(Byte Ptr struct)
Print "i: " + struct.i
Print "f: " + struct.f
Print "s: " + String.FromCString(struct.S)
FreeStruct( struct)
Print "ptr: " + Int(Byte Ptr struct)

test.c:
typedef struct {
	int i;
	float f;
	char* s;
} STRUCT;

void CreateStruct( STRUCT** out, int i, float f, char* s) {
	STRUCT* sc = (STRUCT*)malloc( sizeof( STRUCT));
	sc->i = i;
	sc->f = f;
	sc->s = s;
	*out = (char*)sc - 4; // this is the important part!
}

STRUCT* CreateStruct2( int i, float f, char* s) {
	STRUCT* sc = (STRUCT*)malloc( sizeof( STRUCT));
	sc->i = i;
	sc->f = f;
	sc->s = s;
	return (char*)sc - 4; // this is the important part!
}

void FreeStruct( STRUCT** sc) {
	if( (*sc)->s) free( (*sc)->s); // make sure we free the string, if any
	free( *sc);
	*sc = (void*)0;
}



Gavin Beard(Posted 2007) [#5]
ah thats great thank u, will have a bit of a play


Gavin Beard(Posted 2007) [#6]
dont suppose u have n e example of using a c++ class from within max>


Gavin Beard(Posted 2007) [#7]
*cough* bump ;-)


Brucey(Posted 2007) [#8]
Other than the example that comes with Max ?

(see Advanced Topics in the Language Help section)
It's not much, but it gives you an idea of how it works.

Fine if you are writing your own C++ classes, not so easy if you are using someone elses (like in a library or such).

I find myself writing glue code :

glue.cpp
...

extern "C" {
    bool qt_action_isChecked(MaxQAction * action);
}

...

bool qt_action_isChecked(MaxQAction * action) {
	return action->isChecked();
}


...


myprog.bmx
Extern
    Function qt_action_isChecked:Int(action:Byte Ptr)
End Extern

The action Byte Ptr is the pointer to a C++ object, which was created elsewhere using C++ like
MaxQAction * qt_new_Action(void * handle, QWidget * parent) {
	MaxQAction * action = new MaxQAction(handle, parent);
	return action;
}

which is also called from Max...

I'm sure there are other (better) ways to go about it.


Gavin Beard(Posted 2007) [#9]
Ah thx Brucey, your a star..

fyi. thx for the LibXML module, just started using for a current project :-)