[Solved] NG LoadLibraryA/GetProc conflicting types
BlitzMax Forums/BlitzMax NG/[Solved] NG LoadLibraryA/GetProc conflicting types
| ||
It seems the external DLL library loading is also a problem error: conflicting types for 'LoadLibraryA' extern BBINT __stdcall LoadLibraryA(BBBYTE * bbt_dll); note: previous declaration of 'LoadLibraryA' was here WINBASEAPI HMODULE WINAPI LoadLibraryA (LPCSTR lpLibFileName); error: conflicting types for 'GetProcAddress' extern BBBYTE* __stdcall GetProcAddress(BBINT bbt_libhandle,BBBYTE * bbt_func); note: previous declaration of 'GetProcAddress' was here WINBASEAPI FARPROC WINAPI GetProcAddress (HMODULE hModule, LPCSTR lpProcName); Anybody got a solution? |
| ||
Hiya, Are you defining it yourself? If so there's no need to as it's been defined but I can't remember where :p The problem comes because legacy 'max used integers (32bit) to represent byte pointers, which is ok on a 32bit system, but ng supports 64bit too so the return value needs to fit in a 64bit variable. Therefore the return value for LoadLibraryA/W is changed to a Byte Ptr. A Byte Ptr will resolve to a 32 or 64 bit byte pointer automatically depending on the build option :p Local lib:Byte Ptr = LoadLibraryA("mydll.dll") works here without a probrlem. Hope it helps |
| ||
Ahh, I just took more notice of your post here and some previous post regarding cleaning modules. It looks as though you may have removed the .x file that it used to prevent the confliction? It will be in the modules folder ( which, after looking, should be in \pub.mod\win32.mod. There should be several .x files in there. |
| ||
Hey col, thanks. No I'm just trying to use a simple DLL to test with NG. Obviously this works in vanilla but again it's been tricky with NG. I have not removed any files, about 8 .x files are still there. |
| ||
Yes and also sorry if it might confuse you with the cleaning modules that I have asked in another thread, it is totally unrelated to this issue apparently. |
| ||
Ok so I set my lib to byte ptr..Global lib:Byte Ptr now I'm getting 'Unable to convert from Byte Ptr to Int.' at this part.. Function GetProcWin32@ Ptr( proc$ ) Local p@ Ptr p = GetProcAddress( lib, proc ) <--- ERROR HERE If ( p ) Return p Print "Error" + proc End EndFunction |
| ||
Hi, this seems to work: Strict Global lib:Byte Ptr = LoadLibraryA("user32") If Not lib DebugLog "LoadLibrary failed !" Else DebugLog "OK!" EndIf Local func:Byte Ptr = GetProcWin32("CopyIcon") Function GetProcWin32:Byte Ptr( proc:String ) Local p:Byte Ptr = GetProcAddress( lib, proc ) If Not p Then Print "Error: " + proc; End Return p EndFunction -Henri |
| ||
thanks Henri, Sorry for not completing, but this is how my function is setup: Type DLL Global lib Function OpenDLL( path$ ) DLL.lib = LoadLibraryA( path ) End Function DLL.LibFunction1 = DLL.GetProcWin32("function1") DLL.LibFunction2 = DLL.GetProcWin32("function2") ... Function GetProcWin32( proc$ ) p = GetProcAddress( DLL.lib, proc ) End Function End Type On top of that, it has these Externs: Extern "win32" Function LoadLibraryA( dll$z ) Function GetProcAddress( libhandle%, func$z ) EndExtern I thought it's gonna resolve on the part.. Also not sure what does the "z" stand at the end of that string (string pointer?) but apparently it works on vanilla and it's my first time seeing that. |
| ||
IIRC $z is a null-terminated C-tyle string |
| ||
As xlsior said, when you are passing a Blitz-string to an external function the string is converted to array of bytes with a null terminator. If this reserved memory is not freed the a small memory leak is introduced. The 'z' after string definition will internally call memfree to free the reserved memory. Otherwise you have to do it yourself. Your problem is in Function GetProcAddress( libhandle%, func$z )where libhandle is defined as int (%) when it should be byte ptr. Or if you comment out all the Externs it should work. Also it would make debugging easier if 'Strict' is used. -Henri |
| ||
Yes, I'm using Strict and when I comment out the Externs, I'm now getting Identifier 'loadlibrarya' not found. I'm building a module that loads a DLL library if that makes any difference.. |
| ||
Hey, finally thanks a lot guys. That did it!!! What I did.. Remove Externs as you suggested Henri, thanks! Set lib variable to Byte Ptr (by col, thanx!) and this will search for LoadLibraryA so I import Pub.Win32 which I assume has the conflicting LoadLibraryA extern in the first place (did a search) :-) Now it builds and links apps perfectly :D! BTW. what is the equivalent of variablename ptr ptr in NG?? I just removed the ptr ptr and so far it runs ok (I hope) |
| ||
Hey, finally thanks a lot guys. That did it!!! What I did.. Remove Externs as you suggested Henri, thanks! Set lib variable to Byte Ptr (by col) and this will search for LoadLibraryA so I import Pub.Win32 which I assume has the conflicting LoadLibraryA extern in the first place (did a search) :-) Now it builds and links apps perfectly :D! BTW. what is the equivalent of variablename ptr ptr in NG?? I just removed the ptr ptr and so far it runs ok (I hope) Edit: just removed the extra ptr, I forgot I already asked this on another thread.. variablename ptr -> OK |
| ||
Yes, when calling functions that go to the OS ( or c/c++ code ) then its always good to know the true parameter and return types that the function is expecting. If it expects or returns a pointer other than the usual short,int,float,double then you will probably need a Byte Ptr. Strings are slightly different in that you can use $z to auto convert to a char* or $w to auto convert to a short* or wchar_t* etc, or alternatively use a Byte Ptr for a char* and Short Ptr for a short*/wchar_t*. Experience will help get to know which one to use just by looking at the c/c++ function protoype. NG is more accurate with using the correct datatype than legacy max is due to the nature of requiring 64bit pointers for a 64bit build. Your confliction actually came from you redefining the function incorrectly ;-) If the function wasn't defined ( as it wasn't until you imported pub.win32 ) and you get a confliction then you could create a .x file yourself, in the same folder as the file that has the conflicting function, and put the function protoype/defintion inside it, this would then be used to resolve the conflict automatically. Also be aware than if you use SuperStrict then functions with no return type will return void on the C side of things ( NG compiles your 'Max code to C then compiles that C code with GCC to build your exe ), however if you use Strict then all parameters/return values will default to an integer. It caught me a few times at first. :D |
| ||
Thanks for the additional info Dave. Yes, clearly this was a blitzmax newbie mistake from me as I just really want to go with the .x file method but apparently I don't know how to do those conversions, do you? I would like to know how those X redefinition fix works. :-) |
| ||
I don't know its capabilities other than allowing you to define a function that ends with ! ( the C 'not' operator ) and bcc will 'not' output a function definition for it, thereby the C code will use the original one defined in a header file somewhere. I could be totally wrong here and Brucey is the best one to give a better explanation of it, and also to explain if it could be used for anything else. I'd also imagine that it has something to do with the gazillion different datatypes that the Win32API uses. And at the end of the day all of those datatypes resolve down to the regular C standard types which NG outputs to - thereby making everything compatible. All I know is that you can put the offending function in it with its proper C parameter types, stick a ! on the end and then things compile and work :D Sorry I couldn't explain any deeper and Brucey is the one to answer the question more accurately - I'm probably miles off :D |
| ||
Thanks and no worries Dave! Those info really helped me get a better understanding with some adjustments to NG and how they work. :D appreciate it, cheers. |