Linking problems when using WinAPI functions

BlitzMax Forums/BlitzMax Programming/Linking problems when using WinAPI functions

Fabian.(Posted 2007) [#1]
Hi,
I've some problems when linking to some WinAPI functions, the linker tells me that there's an undefined reference, however I'm sure this function exists:
Strict
Framework brl.blitz

Global Variable

Local ModHandle
If GetModuleHandleExW ( 6 , Varptr Variable , Varptr ModHandle )
  WriteStdout "The memory used for this variable is located in the following module: " + ModHandle + "~n"
EndIf

Extern "Win32"
  Function GetModuleHandleExW ( Flags , Name:Byte Ptr , ModHandle Ptr )
EndExtern
This gives me an error when linking, however, this works:
Strict
Framework brl.blitz

Global Variable

Local Kernel32 = LoadLibraryW ( "Kernel32.dll" )
Local GetModuleHandleExW ( Flags , Name:Byte Ptr , ModHandle Ptr ) "Win32" = GetProcAddress ( Kernel32 , "GetModuleHandleExW" )
Local ModHandle
If GetModuleHandleExW ( 6 , Varptr Variable , Varptr ModHandle )
  WriteStdout "The memory used for this variable is located in the following module: " + ModHandle + "~n"
EndIf
FreeLibrary Kernel32

Extern "Win32"
  Function LoadLibraryW ( Name$w )
  Function GetProcAddress:Byte Ptr ( Library , Name$z )
  Function FreeLibrary ( Library )
EndExtern
I've also noticed some other functions which can't be linked: GetProcessMemoryInfo, EnumProcesses, EnumProcessModules, GetModuleBaseName, GetProcessImageFileName, AuthzFreeHandle, GetProcessId, DebugActiveProcessStop, CredFree, GetNativeSystemInfo

Now I'm wondering what Extern "Win32" actually does.
Till now I thought it puts a notice into the compiled executable which indicates that the executable's code needs these functions. When the operating system executes this application, it checks whether these functions are available and if they are, it loads the modules of the required libraries and links them to the code in the executable, only if this was successfully it really executes the code. If there were problems with loading the libraries or if the functions aren't available it produces a system error message.

Since the code above doesn't work, I'm currently believing BlitzMax links the extern declarations to a static library which does the run-time linking. And this library isn't up-to-date and therefore doesn't support the functions I listed. This could be an explanation for why the functions I listed above can't be linked to. However, if this is true, I don't like this behaviour; it would be much better if BlitzMax would directly link to the dynamic libraries, not using any static c-like library doing this job.

The solution I found is just doing like I did in the second code box: load the library manually while the application is running and then query the function's address. It works, however, if the functions are not available I'm forced to display an error message myself, this would be an application defined notify box or something like this, but it isn't the system standard. I'd prefer that the process wouldn't start at all if the function's aren't available and the operating system checks whether the functions are available and produces a system standard error message if not.


skidracer(Posted 2007) [#2]
"Win32" impacts name mangling and calling convention. The problems you are experiencing I imagine are caused from blitzmax linking with mingw's libkernel32.a file which possibly needs updating.


marksibly(Posted 2007) [#3]
Hi,

Extern just means that a bunch of symbols are to be found 'elsewhere' at link time.

In the case of win32 calls, this means in the mingw static libs. However, it looks like some calls are missing. You'll have to use GetProcAddress to get at these...

Max does it this way because it's the most platform agnostic method - ie: it fits in nicely with the way Linux and MacOS work.


Fabian.(Posted 2007) [#4]
Well, ok. If BlitzMax links to the mingw libs and these libs are out of sync, then it's not a BlitzMax bug.
However, this behaviour is still not comfortable when programming on windows.
Max does it this way because...
If you say so, it sounds like there's another way, and that's what I think, too: it's just to do whatever this mingw lib does directly in the BMX application, so whatever is done in the lib's object file could also be done in the BMX main object file.
I know that this wouldn't be that crossplattform, but it would still be a nice extra feature for windows, especially because it can also be used to link to non-winapi dynamic link libraries. It would be quite better to do the proper system linking than to load the library manually using LoadLibrary and to make an error message manually, if it doesn't exist, instead of using a standardised system message in the system's default language.

But okey, this is now more a feature request than a bug report.


Fabian.(Posted 2007) [#5]
no chance to see this extra feature in v126?
here is a little illustration how it could look:
Strict
Framework brl.blitz

Global Variable

Local ModHandle
If GetModuleHandleExW ( 6 , Varptr Variable , Varptr ModHandle )
  WriteStdout "The memory used for this variable is located in the following module: " + ModHandle + "~n"
EndIf

Extern "DLL::Kernel32.dll" 'links directly to the dll, no indirection through a mingw-library
  Function GetModuleHandleExW ( Flags , Name:Byte Ptr , ModHandle Ptr )
EndExtern
or, to use a third party lib:
Strict
Framework brl.blitz

FunctionInDLL 7

Extern "DLL::thridparty.dll"
  Function FunctionInDLL ( Param )
EndExtern



Dreamora(Posted 2007) [#6]
The problem is not that BM is out of date or MingW.
Its more because BM uses a massively outdated version of MingW.
Have you tried to use MingW 5 (GCC 3.42) instead (3.1 is nice if you work on Win98 but thats it and as Pre Win2k is officially not supported any longer I have the strong hope that BM 1.26 will respect that as well *as it does on the Apple side where pre 10.3 is not supported as well* and update its libraries to at least win2k. Upfront the RichText, where the current one is at least v4, not v3 as used in MaxGUI)


grable(Posted 2007) [#7]
Yeah, that bothers me as well.
BM should realy be updated to work with the latest MingW version.


Gabriel(Posted 2007) [#8]
BM should realy be updated to work with the latest MingW version.

Amen to that. It's a real pain working with external libraries because many won't compile without recent versions of MinGW and some of BMax's modules won't compile *with* recent versions of MinGW. A MinGW update for BMax is a must IMO.


Dreamora(Posted 2007) [#9]
There is actually only one official module that will not compile: MaxGUI.
And there is libpng for which you have to set the no mmx flag for the compiler, to make it compile if you modified BMK to use a modern cpu setup (pentium-m in my case). But thats no problem. Don't know of many current libs that use MMX instead of SSE - SSE3.
Anyway, perhaps I will create an automatic switching BMK that calls the new mingw for all modules, explicitely sets the no mmx for libpng and switches to the old one for MaxGUI.
Then at least that problem would be solved. At least unless we get a MingW 5 compatiible one (-> GCC 3.42)


FlameDuck(Posted 2007) [#10]
A MinGW update for BMax is a must IMO.
Hear hear!


Fabian.(Posted 2007) [#11]
3.1 is nice if you work on Win98 but thats it and as Pre Win2k is officially not supported any longer...
I agree, this is really a reason to change to the newer versions of MinGW.
However, I still request such a feature like I described above to link directly to dlls without indirection through static libs. this would add a much easier way to link to extern dlls.