new format for extern in NG

BlitzMax Forums/BlitzMax NG/new format for extern in NG

GW(Posted 2016) [#1]
Im not sure how to deal with this each time it comes up.

If I declare an external system function like:
Extern "win32"
	Function GetSystemInfo (si:Byte Ptr)
End Extern

It gcc will throw an error about conflicting protoypes between
extern void __stdcall  GetSystemInfo(BBBYTE* bbt_si)


How are extern system functions handled in NG?

Derron(Posted 2016) [#2]
Via ".x"-files (check the modules folder, some use that approach already).

I am not able to find the post in which Brucey explained the whole thing ("x-file" is not the best keyword to search for)

The issue only arises if a header (say, windows.h) is included somewhere up the chain (in this case, brl.blitz does) and your code happens to extern a function from it.
If the parameters don't match, modern gcc's will complain.
In which case, creating a .x file, and adding the appropriate declaration in it seemed like the least effort. Your code is still compatible with old BlitzMax, as all you've done is add a file that is ignored by it.

When NG's bcc is processing extern functions, it just does a lookup against the file. If your function is there, it can decide whether to declare it in the generated header or not (based on the presence of an exclamation at the end of the line).

It's not particularly pretty, but it was a path I took that required the least amount of work.


Edit: In This Post Brucey explains the .x-files.


GW(Posted 2016) [#3]
Thanks Derron!
Creating the .x file now removes the errors from gcc. However those functions no longer work in the program but i'll try to work around it.

Brucey(Posted 2016) [#4]
You could try creating a Struct that mirrors SYSTEM_INFO and pass that into the function as a varptr, which may work as expected.

Perhaps something like :

 .. mirrored fields
End Struct

End Extern

GetSystemInfo(varptr s)

Note that New is not required for Structs, as it is a stack variable, as opposed to normal heap (malloced) variables.

Generally you can have code that works in both NG and legacy BlitzMax by wrapping some ?bmxng around a Type/Struct :
Struct MyExternalType
?not bmxng
Type MyExternalType
... fields
End Struct
?not bmxng
End Type

but only if the type fields are comparable to mappable BlitzMax primitives. If there's any "array" trickery or such, you would need to use some glue instead.

The other option for all this is C glue, but it may not be required if the above works out :-)

GW(Posted 2016) [#5]
Thanks Brucey, that helps a lot. I didn't know that ?bmxng and structs were there. That's very handy. My lingering issue was that GetSystemInfo() would return different results based on 32 or 64 bit build. I'll try what you suggest.