Making import library from MSVC dll for FB use

Windows specific questions.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Making import library from MSVC dll for FB use

Post by jj2007 »

St_W wrote:
jj2007 wrote:Method 1 chokes with "FreeBasic\bin\win32\ld.exe: cannot find -lxlcall32".
Means that the linker cannot find xlcall32.dll or that the file is invalid. Make sure you use 32-bit FreeBasic for loading a 32-bit DLL (and make sure that the DLL is actually a 32-bit DLL).
Yes, the linker can't find it. That's why it's a good idea to use a full path with LoadLibraryEx.
Your return value signals that you use an outdated (unsupported) version, maybe that's the problem and that version is buggy. My version returns 3072.
Your version is a bit newer, but that doesn't mean it's not "valid". FB cannot load it, because it uses only LoadLibrary. But LoadLibraryEx can load the library, and returns the version correctly.
print XLCallVer
Prints the address of the XLCallVer function, you've to use XLCallVer() to make it work. Still doesn't help if you're using a faulty DLL that cannot be loaded.
You can examine/check the DLL with the dumpbin tool.
Of course it prints the address, but since FB cannot load the library, the proc address is zero, so XLCallVer() will just produce an exception. And I have examined the DLL, of course, it is perfectly valid and works fine with LoadLibraryEx.
St_W
Posts: 1619
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: Making import library from MSVC dll for FB use

Post by St_W »

I can reproduce the issues you mentioned with an old version of XLCALL32.DLL I had installed on an old PC (from Office 10, DLL dated 1999). The error code I'm receiving is:
ERROR_DLL_INIT_FAILED
1114 (0x45A)
A dynamic link library (DLL) initialization routine failed.
So probably the DLL is doing something bad in DllMain, which got fixed in newer versions of the file.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Making import library from MSVC dll for FB use

Post by jj2007 »

You think Microsoft would ship a DLL that "does something bad in Dllmain" and cannot be loaded?
St_W
Posts: 1619
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: Making import library from MSVC dll for FB use

Post by St_W »

jj2007 wrote:You think Microsoft would ship a DLL that "does something bad in Dllmain" and cannot be loaded?
According to this blog post (http://pointlessly.blogspot.com/2007/03 ... h-xll.html) the DLL will load correctly from within Excel only, so I have to assume that it indeed does something weird during initalization. And this wouldn't be the only issue with Microsoft APIs or applications, so IMHO it's perfecly possible. And ultimately the newer versions work, so they must have fixed something.
Btw the blog above also mentions the DONT_RESOLVE_DLL_REFERENCES hack.
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Making import library from MSVC dll for FB use

Post by jj2007 »

St_W wrote:the DLL will load correctly from within Excel only, so I have to assume that it indeed does something weird during initalization
OK, that explains something. Some years ago I tried to load a self-written external DLL from VBA. It took me a while to find out that Excel blocked the attempt with an undocumented trick: It expected a precise value in the esi register on return. Microsoft tries to protect the Office suite from third party DLLs...

Re the DONT_RESOLVE_DLL_REFERENCES hack: On initialisation, XLCALL32 tries to find two functions, MdCallBack and _LPenHelper. Since it doesn't find them (they reside indeed in Excel.exe), the LoadLibrary call fails. With LoadLibraryEx, this attempt will be skipped, and the call succeeds.
dodicat
Posts: 7976
Joined: Jan 10, 2006 20:30
Location: Scotland

Re: Making import library from MSVC dll for FB use

Post by dodicat »

To save loading all the windows stuff.
LoadLibraryEx can be called from kernel32.dll, and dylibsymbol seems to pair well with it, even when DONT_RESOLVE_DLL_REFERENCES (1) is not used.

Code: Select all


Extern "Windows"
Declare Function LoadLibraryEx Alias "LoadLibraryExA"(Byval As zstring Ptr, Byval As Any Ptr,Byval As Long) As Any Ptr
End Extern


Dim version As Function() As Long
Dim As Any Ptr L=LoadLibraryex("XLCall32.dll",0,1)
If L=0 Then Print "Unable to load":Sleep:End

version = Dylibsymbol(L,"XLCallVer")


If version Then
    Print "Version = "; version()
Else
    Print  "function not found"
End If
Sleep



 
St_W
Posts: 1619
Joined: Feb 11, 2009 14:24
Location: Austria
Contact:

Re: Making import library from MSVC dll for FB use

Post by St_W »

dodicat wrote:To save loading all the windows stuff.
LoadLibraryEx can be called from kernel32.dll, and dylibsymbol seems to pair well with it [...]
It wasn't about the inclusion of windows headers when I wrote that it can be done with FB built-ins (as we are talking about Excel it will be win-only anyway), I just couldn't understand why only direct win32 calls should work. Thanks to jj2007's closer look into the library I can see now why that workaround is even needed. Yet, there are many questions: for example, will the library work when loaded that way ? and what else is done during xlcall32's initialization and what of it is needed? I guess that the library can only be correctly used from within Excel anyway, and then you should be able to use the library functions provided by FB, too.

Anyway, a very interesting find.
E Dingsor
Posts: 24
Joined: Nov 15, 2017 9:53
Location: Norway

Re: Making import library from MSVC dll for FB use

Post by E Dingsor »

Problem solved(hopefully). First I had to clean up different fileversions etc from file catalog, but the main culprit I believe was an early lib filevesrion that somehow had ended in \lib catalog of freebasic . Whatever solutions I tried, the compiler chose that early(and obviously wrong version) lib version.

What I did:
Used pexports.exe on xlcall32.dll

to create xlcall32.def

Code: Select all

[LIBRARY XLCall32.dll
EXPORTS
Excel4
Excel4v
LPenHelper
XLCallVer
Then I used dlltool.exe(shipped with FB) like this

>dlltool -k -d xlcall32.def -l libxlcall32.dll.a

Then I used Dumpbin.exe (from Microsoft VS2014) like this : Dumpbin /exports libxlcall32.dll.a
and got.

Code: Select all

File Type:  LIBRARY
Exports
Ordinal	Name
		_Excel4
		_Excel4v
		_LPenHelper
		_XLCallVer
Summary
		..
		...

test.bas

Code: Select all

#pragma once
#DEFINE __FB_WIN32__

#DEFINE __FB_LANG__
#include once "crt/long.bi"
#include once "windows.bi"
 type LPXLOPER AS DWORD
    
 
#inclib "libxlcall32"


extern "Windows" 'lib "xlcall32.dll"
declare  FUNCTION XLCallVer pascal ALIAS "XLCallVer"() AS LONG
end extern

extern "C"  'lib "xlcall32.dll"
DECLARE FUNCTION Excel4   ALIAS "Excel4"(byval xlfn as long, byval operRes as LPXLOPER, byval count as long, ...) as LONG
end extern
TYPE lpxloper as dword
   dim lborder as long
    dim xf as long,count as long
   dim ffoper as LPXLOPER
   lborder = XLCallVer()
   print lborder
   xf = 4
   count = 0
   
   lborder = Excel4(xf,ffoper,count,)
   print lborder
   SLEEP
END
I can also choose to omit #inclib "libxlcall32" when compiling, but need then
change code to
extern "Windows" lib "xlcall32.dll"
declare FUNCTION XLCallVer pascal ALIAS "XLCallVer"() AS LONG
end extern

extern "C" 'lib "xlcall32.dll"
DECLARE FUNCTION Excel4 ALIAS "Excel4"(byval xlfn as long, byval operRes as LPXLOPER, byval count as long, ...) as LONG
end extern


xlcall32.dll has to reside in same catalog as compiled exe


now onto more code conversions!
Thanks for help and suggestions
\E
jj2007
Posts: 2326
Joined: Oct 23, 2016 15:28
Location: Roma, Italia
Contact:

Re: Making import library from MSVC dll for FB use

Post by jj2007 »

I understand that you prefer static linking, but looking at xlcall32.dll, it is just a stub, 73 lines of assembler code, which does not provide any functionality other than calling Excel itself. It depends on other components that must be present on the user's machine - and we discussed above possible reasons why LoadLibrary fails but LoadLibraryEx(..., DONT_RESOLVE_DLL_REFERENCES) succeeds. Which means that static linking is pretty useless, since xlcall32.dll and its dependencies must be present anyway. Your exe will be 32k shorter if you use dynamic linking.
xlcall32.dll has to reside in same catalog as compiled exe
You could use the full path to the DLL for LoadLibrary. Test if it works a) inside the folder where Excel.exe sits, b) outside. If it fails outside, an option is to temporarily set the Excel.exe folder with SetCurrentDirectory, load the DLL, restore the old current folder. The exact procedure depends on the user's configuration, test it with different ones to avoid surprises.
E Dingsor
Posts: 24
Joined: Nov 15, 2017 9:53
Location: Norway

Re: Making import library from MSVC dll for FB use

Post by E Dingsor »

jj,
I hear you. For my test.exe the xlcall32.dll must reside in same folder or in windows folder. Reason for using static linking vs dynamic is due to how MS lay out the coding in their EXCEL SDK. My end product will be fb files(.bi, .dll.a,inc,.o) that will compile into an xll file which only purpose is to expose user defined functions and procs to work with Excel as an "intergrated" part of the program itself.

My test program was only to get the declares etc working.
\E
Post Reply