B4R Question Pass user defined type to inline-c

Mostez

Well-Known Member
Licensed User
Longtime User
I want to pass three vars to inline-c code, the three vars are defined within 'Type'
I want to do something like this
B4X:
Type mChar(Page As Byte, Col As Byte, Data as Byte)
Edit: I forgot to add this part of code to call the inline-c sub

B4X:
mChar.Page = 1
mChar.COL = 8
mChar.Data = 0xF1
RunNative("drawchar",mChar)

B4X:
void drawchar(B4R::Object* o) {
page = o.Page
col = o.Col
data = o.Data
do something...
...
}
Thanks
 
Last edited:

hatzisn

Expert
Licensed User
Longtime User
I have very limited knowledge of C++ but shouldn't you cast the object o to the type?
Something like this:

C++:
void drawchar(B4R::Object* o) {
b4r_main::_mchar mch;
mch = (b4r_main::_mchar) o;
page = mch.page
col = mch.col
data = mch.data
//do something...
//everything in lower case
...
}
 
Last edited:
Upvote 0

Mostez

Well-Known Member
Licensed User
Longtime User
thanks @hatzisn, I edited the question, sorry it was my mistake, I want to recall 'mChar' elements in the inline-c after passing it from B4R code by 'RunNative', in this case the object (o)
 
Upvote 0

hatzisn

Expert
Licensed User
Longtime User
I want to pass three vars to inline-c code, the three vars are defined within 'Type'
I want to do something like this
B4X:
Type mChar(Page As Byte, Col As Byte, Data as Byte)
Edit: I forgot to add this part of code to call the inline-c sub

B4X:
mChar.Page = 1
mChar.COL = 8
mChar.Data = 0xF1
RunNative("drawchar",mChar)

B4X:
void drawchar(B4R::Object* o) {
page = o.Page
col = o.Col
data = o.Data
do something...
...
}
Thanks

Another option would be to create a variable as mChar and set its propeties in B4R and then call it in in-line C. Somethin like that:

B4R:
B4X:
Sub Process_Globals
    Public Serial1 As Serial
    Type mChar(Page As Byte, Col As Byte, Data as Byte)
    Dim mch As mChar
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
    mChar.Page = 1
    mChar.COL = 8
    mChar.Data = 0xF1


RunNative("drawchar", Null)
End Sub

C++ In Line code:
C++:
void drawchar(B4R::Object* o) {
byte page;
byte col;
byte data;

page = b4r_main::_mch.page
col = b4r_main::_mch.col
data = b4r_main::_mch.data
//do something...
//everything in lower case
//...
}
 
Last edited:
Upvote 0

hatzisn

Expert
Licensed User
Longtime User
Another option would be to create a variable as mChar and set its propeties in B4R and then call it in in-line C. Somethin like that:

B4R:
B4X:
Sub Process_Globals
    Public Serial1 As Serial
    Type mChar(Page As Byte, Col As Byte, Data as Byte)
    Dim mch As mChar
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
    mChar.Page = 1
    mChar.COL = 8
    mChar.Data = 0xF1


RunNative("drawchar", Null)
End Sub

C++ In Line code:
C++:
void drawchar(B4R::Object* o) {

page = b4r_main::_mch.page
col = b4r_main::_mch.col
data = b4r_main::_mch.data
//do something...
//everything in lower case
...
}

Ingore this, my bad due to lack of C++ knwoledge.
 
Upvote 0

tigrot

Well-Known Member
Licensed User
Longtime User
This is code from Erel, which passes an array to inline C
B4X:
Private Sub AppStart
   Serial1.Initialize(115200)
   Log("appstart")
   Dim bb() As Byte = "abc"
   RunNative("PassBytes", bb)
End Sub

#if C
  void PassBytes(B4R::Object* o) {
   B4R::Array* b = (B4R::Array*)B4R::Object::toPointer(o);
     char* c = (char*)b->data;
   ::Serial.println(c);
  }
#end if

You could pass an array instead of a user Type.

Ciao
Mauro
 
Last edited:
Upvote 0

Mostez

Well-Known Member
Licensed User
Longtime User
thanks @tigrot, for example how can I get element 2 in 'b' array (inline-c code), in this case letter (c) ? something like
char x = b(2)
do something with x ...

TIA
EDIT: ok, I got it, this example prints element 2, ascii char 'A'

B4X:
Private Sub AppStart
    Serial1.Initialize(115200)
    Log("appstart")
    Dim bb() As Byte = Array As Byte (1,2,65,4) ' 65 ascii 'A'
    RunNative("PassBytes", bb)
End Sub

#if C
  void PassBytes(B4R::Object* o) {
   B4R::Array* b = (B4R::Array*)B4R::Object::toPointer(o);
    char* c = (char*)b->data;
 
   ::Serial.println(c[2]);
  }
#end if
 
Last edited:
Upvote 0

tigrot

Well-Known Member
Licensed User
Longtime User
thanks @tigrot, for example how can I get element 2 in 'b' array (inline-c code), in this case letter (c) ? something like
char x = b(2)
do something with x ...

TIA
EDIT: ok, I got it, this example prints element 2, ascii char 'A'

B4X:
Private Sub AppStart
    Serial1.Initialize(115200)
    Log("appstart")
    Dim bb() As Byte = Array As Byte (1,2,65,4) ' 65 ascii 'A'
    RunNative("PassBytes", bb)
End Sub

#if C
  void PassBytes(B4R::Object* o) {
   B4R::Array* b = (B4R::Array*)B4R::Object::toPointer(o);
    char* c = (char*)b->data;

   ::Serial.println(c[2]);
  }
#end if
That's standard C! Array are 0 based, so [2] means third element.
You did it!
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
B4X:
Sub Process_Globals
    Public Serial1 As Serial
    Type myDataType(a As Byte, b As Byte, c As Byte)
End Sub

Private Sub AppStart
    Serial1.Initialize(115200)
    Log("AppStart")
    Dim myData As myDataType
    myData.a = 1
    myData.b = 2
    myData.c = 3
    RunNative("MyFunction",myData)
End Sub

#if C

void MyFunction(B4R::Object* o)
{
    _mydatatype* tmp = (_mydatatype*)B4R::Object::toPointer(o) ;
    ::Serial.println(tmp->b);
}
#End If
hope it helps.
 
Upvote 0

Mostez

Well-Known Member
Licensed User
Longtime User
thank you so much, will give it a try. i have a little question, how to get the value of the elements back in inline-c like:
tmp.a , which equals to 2 in this case
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
In my example code tmp is a pointer to the type, so you need to use the -> construct
B4X:
// in inline code
something = tmp->a;         // will return value in field a in tmp
somethingelse = tmp->b;  // value in field b
lastone = tmp->c;              // value of field c
 
Upvote 0

Mostez

Well-Known Member
Licensed User
Longtime User
In my example code tmp is a pointer to the type, so you need to use the -> construct

your example works perfect, I have one more question if you don't mind. If mBitmap contains an array of bytes, how to get it back in inline C code?
this is the type I use
B4X:
Type mBitmap (X As Byte, Y As Byte, SizeX As Byte, SizeY As Byte, Bitmap() As Byte)

I want to do something like;
something[] = mBitmap ->Bitmap;

TIA
 
Upvote 0

Daestrum

Expert
Licensed User
Longtime User
try this example (maybe not the best)
B4X:
B4R::Object* Jimbo(B4R::Object* o){
    // _atype = Type aType(a As Int, b As Int, c As String,d(4) As Byte)
    // Dim myData as aType
    // myData has its members set ie myData.a = 10       . etc
    // called in B4R = RunNative("jimbo",myData)
   
    _atype* tmp = (_atype *)B4R::Object::toPointer(o);     // get object
    B4R::Array* b = tmp->d;                             // get the array called d
    byte* theBytes = (byte*)b->data;                    // convert data to bytes
    byte u = theBytes[1];                                // get 2nd byte
    ::Serial.println(u,16);                                // print it :)
}
 
Upvote 0
Top