January 21, 2016
On Thursday, 21 January 2016 at 22:14:25 UTC, Dibyendu Majumdar wrote:
> On Thursday, 21 January 2016 at 22:09:47 UTC, jmh530 wrote:
>> The -L/LIBPATH:c:\lib gives me an error that
>> OPTLINK : Warning 9: Unknown Option : LIBPATH
>> and then gives the path I put is not found.
>>
>> At least when it's outputting the text, it's combining
>> :C:\lib\yourlib.lib
>> so it seemingly is finding it.
>
> OPTLINK is for 32-bit code - the options I showed are for 64-bit, which uses MS LINK. You get 64-bit code by adding -m64.
>
> Regards

Thanks. I had been trying to get 32bit code to work. I don't think I did anything special with gcc to compile the dll as 64bit. Anyway, this is what I get when I try it again (stuff in brackets I replaced).

C:<folder>>dmd -m64 <file>.d -L/LIBPATH:C:<folder> -L//IMPLIB:<libfile>.lib
LINK : warning LNK4044: unrecognized option '//IMPLIB:<libfile>.lib'; ignored
callC0.obj : error LNK2019: unresolved external symbol <cfunction> referenced in f
unction _Dmain
callC0.exe : fatal error LNK1120: 1 unresolved externals
--- errorlevel 1120

January 21, 2016
On Thursday, 21 January 2016 at 22:23:36 UTC, jmh530 wrote:
> Thanks. I had been trying to get 32bit code to work. I don't think I did anything special with gcc to compile the dll as 64bit. Anyway, this is what I get when I try it again (stuff in brackets I replaced).
>
> C:<folder>>dmd -m64 <file>.d -L/LIBPATH:C:<folder> -L//IMPLIB:<libfile>.lib
> LINK : warning LNK4044: unrecognized option '//IMPLIB:<libfile>.lib'; ignored
> callC0.obj : error LNK2019: unresolved external symbol <cfunction> referenced in f
> unction _Dmain
> callC0.exe : fatal error LNK1120: 1 unresolved externals
> --- errorlevel 1120

Sorry the option should be -L/IMPLIB:.. - with single slash but you only need this if you are trying to create a shared library which presumably you are not?

I believe to create a static library you need to use -lib, else it is an app so you need to supply a main function.

Regards

January 21, 2016
On Thursday, 21 January 2016 at 22:35:29 UTC, Dibyendu Majumdar wrote:
>
> Sorry the option should be -L/IMPLIB:.. - with single slash but you only need this if you are trying to create a shared library which presumably you are not?
>
> I believe to create a static library you need to use -lib, else it is an app so you need to supply a main function.
>
> Regards

The single slash didn't make a difference. I tried that myself before posting. I got the same error.

I'm not trying to created a shared library in D. My goal is to use a shared library from C in D. Right now, I'm working with a simple test case to make sure I could understand it before working with the actual shared library I want to use.

I recall some discussion in LearningD (don't have it in front of me now) that different types of shared libraries are needed on 32bit vs. 64bit because there is a different linker. This is what I did to created the shared library:

gcc -Wall -fPIC -c <file>.c -I.
gcc -shared -o <libfile>.dll <file>.o -I.
implib <libfile>.lib <libfile>.dll
January 21, 2016
I also added an enhancement request:
https://issues.dlang.org/show_bug.cgi?id=15588


January 21, 2016
On Thursday, 21 January 2016 at 22:49:06 UTC, jmh530 wrote:
>
> I'm not trying to created a shared library in D. My goal is to use a shared library from C in D. Right now, I'm working with a simple test case to make sure I could understand it before working with the actual shared library I want to use.
>
> I recall some discussion in LearningD (don't have it in front of me now) that different types of shared libraries are needed on 32bit vs. 64bit because there is a different linker. This is what I did to created the shared library:
>
> gcc -Wall -fPIC -c <file>.c -I.
> gcc -shared -o <libfile>.dll <file>.o -I.
> implib <libfile>.lib <libfile>.dll

Okay then you don't need the /IMPLIB option. But you do need to specify the library via -L as I mentioned before.

i.e. use:

dmd -m64 -L/LIBPATH:<path to lib> -L<library name> prog.d

Where <library name> is yourlib.lib and this is present along with the DLL in the path you gave.

Plus your prog.d needs to have appropriate code. Example:

module app;

extern (C) void testing();

void main()
{
	testing();
}

Here testing() is provided in the DLL.
January 21, 2016
On Thursday, 21 January 2016 at 22:54:26 UTC, Dibyendu Majumdar wrote:
> On Thursday, 21 January 2016 at 22:49:06 UTC, jmh530 wrote:
>>
>> I'm not trying to created a shared library in D. My goal is to use a shared library from C in D. Right now, I'm working with a simple test case to make sure I could understand it before working with the actual shared library I want to use.
>>
>> I recall some discussion in LearningD (don't have it in front of me now) that different types of shared libraries are needed on 32bit vs. 64bit because there is a different linker. This is what I did to created the shared library:
>>
>> gcc -Wall -fPIC -c <file>.c -I.
>> gcc -shared -o <libfile>.dll <file>.o -I.
>> implib <libfile>.lib <libfile>.dll
>
> Okay then you don't need the /IMPLIB option. But you do need to specify the library via -L as I mentioned before.
>
> i.e. use:
>
> dmd -m64 -L/LIBPATH:<path to lib> -L<library name> prog.d
>
> Where <library name> is yourlib.lib and this is present along with the DLL in the path you gave.
>
> Plus your prog.d needs to have appropriate code. Example:
>
> module app;
>
> extern (C) void testing();
>
> void main()
> {
> 	testing();
> }
>
> Here testing() is provided in the DLL.

I ran

dmd -m64 <file>.d -L/LIBPATH:<path to lib> -L<library name>

and got

<library name> : fatal error LNK1136: invalid or corrupt file
--- errorlevel 1136

At least that's progress.

LNK1136 is for a corrupt or abnormally small file. I did notice that the original dll was 82kb and the lib file was 2kb.
January 22, 2016
On Thursday, 21 January 2016 at 23:07:06 UTC, jmh530 wrote:
> On Thursday, 21 January 2016 at 22:54:26 UTC, Dibyendu Majumdar wrote:
>> On Thursday, 21 January 2016 at 22:49:06 UTC, jmh530 wrote:
>>>
>>> I'm not trying to created a shared library in D. My goal is to use a shared library from C in D. Right now, I'm working with a simple test case to make sure I could understand it before working with the actual shared library I want to use.
>>>
>>> I recall some discussion in LearningD (don't have it in front of me now) that different types of shared libraries are needed on 32bit vs. 64bit because there is a different linker. This is what I did to created the shared library:
>>>
>>> gcc -Wall -fPIC -c <file>.c -I.
>>> gcc -shared -o <libfile>.dll <file>.o -I.
>>> implib <libfile>.lib <libfile>.dll
>>
>> Okay then you don't need the /IMPLIB option. But you do need to specify the library via -L as I mentioned before.
>>
>> i.e. use:
>>
>> dmd -m64 -L/LIBPATH:<path to lib> -L<library name> prog.d
>>
>> Where <library name> is yourlib.lib and this is present along with the DLL in the path you gave.
>>
>> Plus your prog.d needs to have appropriate code. Example:
>>
>> module app;
>>
>> extern (C) void testing();
>>
>> void main()
>> {
>> 	testing();
>> }
>>
>> Here testing() is provided in the DLL.
>
> I ran
>
> dmd -m64 <file>.d -L/LIBPATH:<path to lib> -L<library name>
>
> and got
>
> <library name> : fatal error LNK1136: invalid or corrupt file
> --- errorlevel 1136
>
> At least that's progress.

The linker will most certainly get confused by  this "-L<library name>" - as it will take it for an object file. The difference is that a library is a collection of object files.

The GNU linker ld, for instance, uses the -l<libname> switch for adding libraries to link against and -L<path> to add a search path to look for the libraries passed in with -l<libname>.

If you leave it to the compiler to invoke the linker you need to remember the -L compiler switch is passing what follows to the linker (minus the -L compiler switch).
I.e. -L-LC:\lib\path will be passed on as "-LC:\lib\path", -L-lsomelib => "-lsomelib", etc.

You won't find help about linker options on any compiler manual. You have to refer to your linker manual.

Also make sure to adhere to naming conventions. It could very well be your linker quits with an error message if you pass it -lsomelib for a file somelib.lib when it expects to find the file libsomelib.lib instead.

> LNK1136 is for a corrupt or abnormally small file. I did notice that the original dll was 82kb and the lib file was 2kb.

The lib for a 'DLL' is small because it just tells the linker where to find the code in the 'DLL' - the actual code is in the 'DLL'.

Hope the helps
January 22, 2016
On Thursday, 21 January 2016 at 23:07:06 UTC, jmh530 wrote:
> I ran
>
> dmd -m64 <file>.d -L/LIBPATH:<path to lib> -L<library name>
>
> and got
>
> <library name> : fatal error LNK1136: invalid or corrupt file
> --- errorlevel 1136
>
> At least that's progress.
>
> LNK1136 is for a corrupt or abnormally small file. I did notice that the original dll was 82kb and the lib file was 2kb.

Have you used pragma(lib)? https://dlang.org/spec/pragma.html#lib  There's also a section on it in Learning D.

I don't use Windows much, but when I link to a dll, that's what I do. I've actually never used -L options on Windows. If I want to call functions from R.dll, I use implib /system R.lib R.dll to create R.lib. Then I put pragma(lib, "R.lib"); in my .d file and compile.
January 22, 2016
On Friday, 22 January 2016 at 00:43:05 UTC, W.J. wrote:
>
> The GNU linker ld, for instance, uses the -l<libname> switch for adding libraries to link against and -L<path> to add a search path to look for the libraries passed in with -l<libname>.
>
> If you leave it to the compiler to invoke the linker you need to remember the -L compiler switch is passing what follows to the linker (minus the -L compiler switch).
> I.e. -L-LC:\lib\path will be passed on as "-LC:\lib\path", -L-lsomelib => "-lsomelib", etc.

The -L-L stuff from the LearningD book is making more sense. The book is using Linux examples, linux uses ld, which has those flags.

>> LNK1136 is for a corrupt or abnormally small file. I did notice that the original dll was 82kb and the lib file was 2kb.
>
> The lib for a 'DLL' is small because it just tells the linker where to find the code in the 'DLL' - the actual code is in the 'DLL'.
>
> Hope the helps

That's clear. Thanks.

January 22, 2016
On Friday, 22 January 2016 at 01:34:00 UTC, bachmeier wrote:
>
> Have you used pragma(lib)? https://dlang.org/spec/pragma.html#lib
>  There's also a section on it in Learning D.
>

Looks like the sections are split apart by a couple hundred pages. I tried it with the .lib I created earlier without much luck. Also note that the LearningD section recommends not using the pragma. At this point, I'd rather just having something working.

> I don't use Windows much, but when I link to a dll, that's what I do. I've actually never used -L options on Windows. If I want to call functions from R.dll, I use implib /system R.lib R.dll to create R.lib. Then I put pragma(lib, "R.lib"); in my .d file and compile.

Thanks for walking through what you do.

I tried to create an example that more closely resembles what is in LearningD (see https://github.com/aldacron/LearningD/tree/master/Chapter09_Connecting%20D%20with%20C/clib). I created two files

clib.c
----------------
#include <stdio.h>

int some_c_function(int);

int some_c_function(int a) {
	printf("Hello, D! from C! %d\n", a);
	return a + 20;
}

and

dclib.d
-----------------
pragma(lib, `libclib.lib`);

extern(C) @nogc nothrow {
	int some_c_function(int);
}

void main()
{
	import std.stdio : writeln;
	writeln(some_c_function(10));
}

------------------
I then ran
gcc -Wall -fPIC -c clib.c
gcc -shared -o libclib.dll clib.o
implib libclib.lib libclib.dll

I'm getting an error on the implib command on my home computer. Maybe running it on a different computer would work.

The LearningD book says that you should compile the libraries with DMC on Windows, but I can't figure out how to generate a shared library on DMC. I didn't get the implib error for what I was working on before.

I feel like getting stuff to work with Windows is always such a hassle, but that's the only way I'll be able to use this stuff at work.