Import Visual Studio .lib

BlitzMax Forums/BlitzMax NG/Import Visual Studio .lib

JoshK(Posted 2016) [#1]
Can BMXNG import a Visual Studio lib that has C functions exposed? (Regular BlitzMax can.) Right now I am getting a lot of undefined reference errors when I try it.


RustyKristi(Posted 2016) [#2]
As far as I know you have to use the same MinGW as your NG version. I have a simple tutorial/question thread for that.

or maybe try this one

http://visualgdb.com/tutorials/mingw/mingw64/


JoshK(Posted 2016) [#3]
It should be possible with MINGW:
http://www.mingw.org/wiki/msvc_and_mingw_dlls


RustyKristi(Posted 2016) [#4]
Yes I have read that part and actually I did some external DLL test (not lib) with NG and MinGW. Looks like the same procedure, just different way of doing it.


JoshK(Posted 2016) [#5]
My lib is a VS lib with a DLL, all cdecl functions. Not sure about the exact details of that, but I am pretty sure it is possible, and it even works with the VS debugger. Feedback, Brucey?


RustyKristi(Posted 2016) [#6]
I see and I already told you to look into my threads. Anyway, I'll just pull them up for you so here is Brucey's response that I think is related to your problem:


You have a C++ DLL that you want to use with BlitzMax?

If it has been built with VS++ then you'll need to build a C-glue dll in VS and link your BlitzMax code to that - because VS and GCC C++ ABIs on Windows are not compatible.


My thread and actual Link here:

http://www.blitzbasic.com/Community/post.php?topic=106468&post=1310380


JoshK(Posted 2016) [#7]
That's exactly how I have always done it. Functions are declared with "__declspec". However, I get errors as if the functions are not detected.

This same setup works fine with regular BMX.


JoshK(Posted 2016) [#8]
You can try a test here:
http://www.leadwerks.com/buildtest.zip

Import "Leadwerks.lib"

Extern "c"
	Function leMat4FromRotation(pitch:Float,yaw:Float,roll:Float,result:Byte Ptr)
EndExtern

Local mat:Float[16]
leMat4FromRotation(0,0,0,mat)

Output:
Building buildtest
[ 99%] Processing:buildtest.bmx
[ 99%] Compiling:buildtest.bmx.gui.debug.win32.x86.c
[100%] Linking:buildtest.debug.exe
C:/Users/Josh/Desktop/.bmx/buildtest.bmx.gui.debug.win32.x86.o: In function `bb_main':
C:/Users/Josh/Desktop/.bmx/buildtest.bmx.gui.debug.win32.x86.c:60: undefined reference to `leMat4FromRotation'
Build Error: Failed to link C:/Users/Josh/Desktop/buildtest.debug.exe
Process complete

Works fine with regular BMX.


GW(Posted 2016) [#9]
You might have to define an '.x' file containing the c version of your declaration.
It's all a bit nebulous about when and why it's needed with NG.


Derron(Posted 2016) [#10]
The .x-file os there in need it you mention/declare an external function again when it already was mentioned by an previously imported module.

At least this is what people have had trouble with.

Bye
Ron


JoshK(Posted 2016) [#11]
More info, please?


eagle54(Posted 2016) [#12]
Try this example :

http://www.blitzbasic.com/Community/post.php?topic=105537&post=1296080


JoshK(Posted 2016) [#13]

This example works correctly, but I am unable to get it working with a VS lib file.

I created a file named "buildtest.x" and added this line:
void leMat4FromRotation(float, float, float, void*)!

I still get the same linking error. I know the .x file is being read because I had to mess around with the syntax before I got it right.
Building buildtest
[ 99%] Processing:buildtest.bmx
[ 99%] Compiling:buildtest.bmx.gui.debug.win32.x86.c
[100%] Linking:buildtest.debug.exe
C:/Users/Josh/Desktop/buildtest/.bmx/buildtest.bmx.gui.debug.win32.x86.o: In function `bb_main':
C:/Users/Josh/Desktop/buildtest/.bmx/buildtest.bmx.gui.debug.win32.x86.c:60: undefined reference to `leMat4FromRotation'
Build Error: Failed to link C:/Users/Josh/Desktop/buildtest/buildtest.debug.exe
Process complete



col(Posted 2016) [#14]
Indeed this should work. It works using the legacy compiler but not in BlitzmaxNG.

I currently have this working with a standalone .lib, as opposed to one with a .dll

Even then it gives a warning so there's still more investigating to do...


JoshK(Posted 2016) [#15]
I updated the test program with my .x file for testing:
http://www.leadwerks.com/buildtest.zip

I also tried with a Visual Studio static lib, with the same result. I'm using VS 2013 right now.


col(Posted 2016) [#16]
For the static lib to kind of work I needed to turn off a linking optimisation in vstudio and compile the 'max code via the command line adding .lib on the command line - its not an automated build process but if finding a solution works out then I'm sure in would get included to be automatic.


JoshK(Posted 2016) [#17]
Thanks for the info. That is consistent with the information here:
http://www.mingw.org/wiki/msvc_and_mingw_dlls

How do I add a command line parameter to the build?


col(Posted 2016) [#18]
I'm sure this isn't a robust solution just yet but this is what I did so far...

In the NG compatible maxIDE:
Turn on verbose output program menu -> build options -> developer options -> verbose build

a fair warning is that it is quite verbose in that the full paths are output so it can look a little much at first.

This will give you the command line used to compile the file(s). There are some steps to look out for for .bmx files:
bcc.exe compiles from .bmx to .h & .c
gcc.exe compiles from .c to .o
ld.exe links .o to .exe

for a module you'll also get
ar.exe used for .o to .a

ld.exe is the linker command that you need to tack the .lib onto the end of. Add something along the lines of -Lfolder/to/library -lLeadwerks. Notice no need for the .lib extension.

In VS dll project in VS:
Project properties -> configuration properties -> general -> project defaults -> whole program optimization -> no whole program optimization

It's very rough - ld.exe warns about an incomplete def table or similar, so I guess something still isn't right.
Also I've only tested by returning a simple integer from a function in the .lib, no parameters.


col(Posted 2016) [#19]
I've also been playing with dlltool and reimp, x86, x64 and I can't get them to link just yet. They do produce a libLeadwerks.a file but linking is still a no-no. Strangely all of the gcc tools will examine the dll and .lib file giving in-depth information about it. But linking gives an invalid format error, which is usually an error ouput for mixing x86 and x64...


JoshK(Posted 2016) [#20]
I added some missing DLLs. I didn't think they would matter during linking, but maybe it does somehow.
http://www.leadwerks.com/buildtest.zip


JoshK(Posted 2016) [#21]
Will this be supported?


Derron(Posted 2016) [#22]
You might better open an issue on github for thia...to keep track on progress/potential regressions etc.

This also raises awareness of Brucey regarding the problem.

Bye
Ron


JoshK(Posted 2016) [#23]
Reported here:
https://github.com/bmx-ng/bmk/issues/26


Brucey(Posted 2016) [#24]
I couldn't get my gcc to link the .lib...

But it's easy to create a compatible .a file instead. There are several ways to achieve this, as listed in the above github issue.

Note that the .x file is not required.
The .x file inhibits the generation of extern function definitions. Generation of such definitions are only a problem if some other included header already defines them - for example, if you are declaring an export of a system function on Windows that would be visible via windows.h. Then you would see an "already defined" error or some such. In such cases you need to prevent the generation of the already defined function.
If you use a .x file to inhibit the generation of a function definition that is not already included via some other header, then you will have no definition of that function. This results in the function being declared with int return type and int arguments - which is probably not what you want.