Inline C question

Previous topic - Next topic

SpongeBob

Hi,

Is it possible to have a C variable, say int A;, that is accessable from various other inlined sections, in other files, spread throughout a multifile project?

I actually need it for a global like C struct that is only used in the C parts of the project code but can't get it to work, either scope errors or multiple definition errors.

Thanks in advance,

Bob

MrTAToad

There are two ways :  You could define the variables in a "global" inline section as global variables, or in a global class.  Something like :
Code (glbasic) Select

INLINE
    int x;
ENDINLINE

FUNCTION test%:
INLINE
   x=27;
ENDINLINE
ENDFUNCTION

SpongeBob

Thank you for your reply,

I tried to make a 2 file project, the 1st with this in it:

Code (glbasic) Select
LOCAL l%
INLINE
l%=xfoo;
ENDINLINE
DEBUG l%


The 2nd with this in it:

Code (glbasic) Select
INLINE
    int xfoo;
ENDINLINE

FUNCTION test%:
INLINE
   xfoo=27;
ENDINLINE
ENDFUNCTION


But I am now getting this error:
Code (glbasic) Select
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_temp0.cpp: In function `int __GLBASIC__::__MainGameSub_()':
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_temp0.cpp:58: error: `xfoo' was not declared in this scope


hardyx

Use this to declare the variable xfoo defined in the other file:

Code (glbasic) Select
LOCAL l%
INLINE
     extern int xfoo;
     l%=xfoo;
ENDINLINE
DEBUG l%


MrTAToad

Usually you would keep all INLINE stuff in one file - otherwise extern is needed...

backslider

Quote from: SpongeBob on 2012-Oct-24
Thank you for your reply,

I tried to make a 2 file project, the 1st with this in it:

Code (glbasic) Select
LOCAL l%
INLINE
l%=xfoo;
ENDINLINE
DEBUG l%


The 2nd with this in it:

Code (glbasic) Select
INLINE
    int xfoo;
ENDINLINE

FUNCTION test%:
INLINE
   xfoo=27;
ENDINLINE
ENDFUNCTION


But I am now getting this error:
Code (glbasic) Select
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_temp0.cpp: In function `int __GLBASIC__::__MainGameSub_()':
C:\Users\Dad\AppData\Local\Temp\glbasic\gpc_temp0.cpp:58: error: `xfoo' was not declared in this scope


Could you try to write this code in the first file:
Code (glbasic) Select

FUNCTION foo:; ENDFUNCTION //dummy function to get out of the GLBASIC namespace
LOCAL l%
INLINE
l%=xfoo;
ENDINLINE
DEBUG l%

MrTAToad

#6
That wont compile - all INLINE stuff needs to be in a function.

Try this :

Code (glbasic) Select
DEBUG "Put 1 : "+put()+"\n"
DEBUG test()+"\n"
DEBUG "Put 2 : "+put()+"\n"


Code (glbasic) Select
INLINE
int xfoo;
ENDINLINE

FUNCTION test%:
INLINE
   xfoo=27;
ENDINLINE
ENDFUNCTION

FUNCTION put%:
INLINE
return xfoo;
ENDINLINE
ENDFUNCTION

SpongeBob

@backslider: Unfortunately our suggestion causes an "temp.gbas"(8) error : command not inside function or sub" error. This could be removed simple by moving the test routine to a function but I think "extern" is the way to go.

@hardyx: "extern" works great but removing the "//" here:

LOCAL l%
INLINE
     extern int xfoo;
     //l%=xfoo;
     DEBUG((DGStr)xfoo);
ENDINLINE

Causes an "*** Unhandled exception ***   EXCEPTION_INT_DIVIDE_BY_ZERO" runtime error. I think this is due to a C to GLBasic type conversion?
It's not really a big deal, as the global C var will only be used within various in-lined C sections scattered between various project files but I would still like to know why it's causing a divide by zero though?

@MrTAToad: Thanks for the suggestion but my project is very segmented into various files, segmented by required function and usually typed. The C code has to be inlined due to the way the code works but communication between C and GLBasic while trying to avoid complex type conversions was causing me no end of bother. There is a lot of C spread across this project, this is unavoidable but I am glad GLBasic has this C integration functionality, what a god-send it has already proven to be!

Thanks to all that helped me here! :)

Schranz0r

Quote from: MrTAToad on 2012-Oct-25
That wont compile - all INLINE stuff needs to be in a function.

Thats NOT right ;)

In the mainfile of your project, if you want to include headerfiles


Code (glbasic) Select
WHILE TRUE
     // stuff here
SHOWSCREEN
WEND
END

// a pointles function to close the namespace of GLBasic
FUNCTION Close_GLB_Namespace:
ENDFUNCTION

INLINE

  #include "mystuff.h"
//...
ENDINLINE


the normal way you can use INLINE-ENDINLINE wherever you want!

Code (glbasic) Select
LOCAL a = 10

INLINE

int i = 2;

a = i;

ENDINLINE

WHILE TRUE


PRINT a,10,10

SHOWSCREEN
WEND
END

I <3 DGArray's :D

PC:
AMD Ryzen 7 3800X 16@4.5GHz, 16GB Corsair Vengeance LPX DDR4-3200 RAM, ASUS Dual GeForce RTX™ 3060 OC Edition 12GB GDDR6, Windows 11 Pro 64Bit, MSi Tomahawk B350 Mainboard

MrTAToad

#9
Thats true = it doesn't always have to be in a function :)

I can see an eBook covering INLINE stuff might be needed after the update comes out  :)

hardyx

#10
Code (glbasic) Select

LOCAL l%

test()    // this puts a value in xfoo (in the other file)
INLINE
extern int xfoo;
l = xfoo;
DEBUG(DGStr(xfoo));
ENDINLINE


This works for me in GLB v 10.283, I don't tested in version 11.x
You must to put the variables in the INLINE without the '%', because "%=" in C is an operator.
The DEBUG line works ok too, and displays the value put in the other file.

P.D. I was not included the other module in the proyect, but now works ok.
P.D.2. If you are curious, the divide by zero error is caused because you are making l %= xfoo in C. This is the modulo assignment operator. This means l = l MOD xfoo with makes a division, and xfoo=0.

SpongeBob

Doh!  :-[ Your quite correct, thank you for pointing that out.