Setting Types in C

BlitzMax Forums/BlitzMax Programming/Setting Types in C

Hi!

How can I set String Fields of BlitzMax Types in an external C function?

I've tried the following:
ref.bmx
SuperStrict

Framework BRL.Blitz

Import "ref.c"
Extern "C"
	Function getTest(test:Byte Ptr)
End Extern

Type TTest
	Field Foo:String
	Field Bar:String
	Field Info:String
	
	Method Debug()
		DebugLog(Foo + " " + Bar + " " + Info)
	End Method
End Type

Local test:TTest = New TTest

For Local i:Int = 0 Until 100
	getTest(test)
	test.Debug()
	Delay 100
Next

End


ref.c
#include <brl.mod/blitz.mod/blitz.h>
#include <windows.h>

typedef struct {
	BBString *Foo;
	BBString *Bar;
	BBString *Info;
} TTEST;

void getTest(TTEST *test) {
	BBRELEASE(test->Foo);
	BBRELEASE(test->Bar);
	BBRELEASE(test->Info)

	test->Foo = bbStringFromCString("Foo");
	test->Bar = bbStringFromCString("Bar");

	char info[255];
	sprintf(info, "%d ms", GetTickCount());
	test->Info = bbStringFromCString(info);
}


both in the same directory.

When I try to run ref.bmx in the debug mode I'am getting:
DebugLog:Foo Bar 2200671 ms
DebugLog:Foo Bar 2200765 ms
DebugLog:Foo Bar 2200875 ms
DebugLog:Foo Bar 2200968 ms
bad refs:obj=$c30670 refs=$7fffffff
String:Foo
bad refs:obj=$c30690 refs=$7fffffff
String:Bar
bad refs:obj=$c306b0 refs=$7fffffff
String:2195937 ms
bad refs:obj=$c30800 refs=$7fffffff
String:Foo
bad refs:obj=$c30820 refs=$7fffffff
String:Bar
...


When I comment out the BBRELEASE-Macro calls, I'am getting false results like:
DebugLog:Bar Bar 2554250 ms
DebugLog:Foo 2616703 ms 2616703 ms


So, how can I set BBStrings-Fields in C correctly?

cu olli

You can't do that in C with BlitzMax... The two "types" are not compatible. There are some posts on the forums which explain how to do something like you want with C++.

And you really don't want to be calling BBRELEASE() if you don't know what you're doing :-p

Hmm, OK thx! ...

It's possible to setting 3 String via calling by reference? Like a function
void getTest2(BBString *Foo, BBString *Bar, BBString *Info) {
	Foo = bbStringFromCString("Foo");
	Bar = bbStringFromCString("Bar");

	char info[255];
	sprintf(info, "%d ms", GetTickCount());
	Info = bbStringFromCString(info);
}


Whats the extern block for it in BMax? String Ptr isn't possible.

cu olli

Any generic pointer can be defined as Byte Ptr.

No way with Byte Ptr, my Strings are alway empty :(

So whats with C++? I've tested this:
Ref.cpp
#include <brl.mod/blitz.mod/blitz.h>
#include <windows.h>

class TTest {
public:
	BBString *a;
	BBString *b;
	BBString *c;

	TTest() {
		a = &bbEmptyString;
		b = &bbEmptyString;
		c = &bbEmptyString;
	}

	virtual ~TTest() {
		a = &bbEmptyString;
		b = &bbEmptyString;
		c = &bbEmptyString;
	}
	
	virtual void getTest() {
		a = bbStringFromCString("Foo");
		b = bbStringFromCString("Bar");
	
		char info[255];
		sprintf(info, "%d ms", GetTickCount());
		c = bbStringFromCString(info);
	}
};


extern "C" {

TTest *CreateTTest(){
	return new TTest;
}

void DestroyTTest(TTest *test) {
	delete test;
}

}


Ref.bmx
SuperStrict

Framework BRL.Blitz

Import "ref.cpp"

Extern 

Type TTest
	Field a : String
	Field b : String
	Field c : String

	Method _pad1() ' padding for virtual destructors
	Method _pad2()
	Method getTest()
End Type

Function CreateTTest:TTest()
Function DestroyTTest(test:TTest)

End Extern

Local test:TTest = CreateTTest()
For Local i:Int = 0 Until 1000
	test.getTest()
	DebugLog test.a + " " + test.b + " " + test.c
	Delay 10
Next

DestroyTTest(test)


Getting some times output like:
DebugLog:FooDebugLog:Foo Bar 4498281 ms
...
DebugLog:Foo 4500109 ms 4500109 ms


Whats wrong?

cu olli

I ended up using getters/setters for stuff like that, and I use cstring($z) to save messing about with BBString.

cpp...
#include <brl.mod/blitz.mod/blitz.h>
#include <windows.h>

class TTest {
public:

	char* a;
	char* b;
	char* c;

	TTest() {
		a = "Foo";
		b = "Bar";
		c = NULL;
	}

	virtual ~TTest() {
		if(a) delete a;
		if(b) delete b;
		if(c) delete c;
	}
	
	virtual void getTest() {
		if(c) delete c;
		c= new char[255];
		sprintf(c, "%d ms", GetTickCount());
	}
	
	virtual char* getA() {return a;}
	virtual char* getB() {return b;}
	virtual char* getC() {return c;}

};


extern "C" {
	TTest *CreateTTest() {return new TTest;}
	void DestroyTTest(TTest *test) {delete test;}
}


bmx..
SuperStrict

Framework BRL.Blitz

Import "ref.cpp"

Extern "C"

Type TTest
	Method _pad1() ' padding for virtual destructors
	Method _pad2()
	Method getTest()
	Method GetA$z()
	Method GetB$z()
	Method GetC$z()
End Type

Function CreateTTest:TTest()
Function DestroyTTest(test:TTest)

End Extern

Local test:TTest = CreateTTest()

For Local i:Int = 0 Until 1000
	test.getTest()
	DebugLog test.geta() + " " + test.getb() + " " + test.getc()
	Delay 10
Next

DestroyTTest(test)


Maybe not ideal, but it works ;)

OK, thank you, thats the way I will going :) I've tested it with
virtual BBString *getA() {
	return bbStringFromCString(a);
}

and it works without bad refs or unexpected results too :)

cu olli