www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - D and .lib files. C++/Other?

reply Damien Gibson <spiceywolf.archaicsoft outlook.com> writes:
Hi... A while back i had some issues with making a usable dll 
file, to which i did manage to figure out... Though while trying 
to use it with C++ i kept getting an error about a corrupted lib 
file...

I had in mind the idea to create a few dlls as me and a few 
friends(Mixed between C++ users and D) but as the issue above I'm 
not sure if I'm doing something wrong or if that's just not a 
possibility, I'm not quite sure WHAT I'm needing to look for to 
find the information about .lib files and how the work and all 
that cause i haven't been able to find anything if there is 
anything.

So from anyone here who's experienced with this stuff (As i can 
find resources about making mixed C++ and D project but nothing 
to do with .lib issues) is it possible to use shared libraries 
between C++ and D, if so is it 2 sided(where each can use the 
others produced dll) or 1 sided (one can use the others but not 
vice versa) as well I had the idea maybe the DMD stuff produces 
incompatible lib files maybe and another compiler or a command 
can produce a compatible one... i have no idea so any suggestions 
are welcome and thank you in advanced for your response!
Jul 01 2017
next sibling parent Damien Gibson <spiceywolf.archaicsoft outlook.com> writes:
Note: I am only on windows as well so i have no idea if the issue 
remains the same for Linux and it may be a windows specific 
issue? Also I was using Visual Studio 2013 C++ so i have no idea 
if its limited to issues there either, I'm on super slow internet 
(Not dialup but might as well be) So i haven't had the ability to 
just download a crap ton of tools and try different shit until i 
got results on my own. (I've done that already within my own 
ability)
Jul 01 2017
prev sibling parent reply Jacob Carlborg <doob me.com> writes:
On 2017-07-01 20:13, Damien Gibson wrote:
 Hi... A while back i had some issues with making a usable dll file, to
 which i did manage to figure out... Though while trying to use it with
 C++ i kept getting an error about a corrupted lib file...
Not sure if this is the issue you're having, but if you're using .lib files on Windows, note that DMD, the D compiler, will by default, on 32bit, output a format (OMF) that is not compatible what Visual Studio is using (COFF). For 64bit, DMD outputs COFF .lib files. For 32bit, use the -m32mscoff flag.
 I had in mind the idea to create a few dlls as me and a few
 friends(Mixed between C++ users and D) but as the issue above I'm not
 sure if I'm doing something wrong or if that's just not a possibility,
 I'm not quite sure WHAT I'm needing to look for to find the information
 about .lib files and how the work and all that cause i haven't been able
 to find anything if there is anything.
Mixing C++ and D DLLs should work. If you're statically linking the DLL, which requires import libraries on Windows, you might have the above issue. -- /Jacob Carlborg
Jul 01 2017
parent reply Damien Gibson <spiceywolf.archaicsoft outlook.com> writes:
 Not sure if this is the issue you're having, but if you're 
 using .lib files on Windows, note that DMD, the D compiler, 
 will by default, on 32bit, output a format (OMF) that is not 
 compatible what Visual Studio is using (COFF). For 64bit, DMD 
 outputs COFF .lib files. For 32bit, use the -m32mscoff flag.
I do happen to be on 32bit only machine right now, my last pc broke recently lol but yeah i tried that mscoff flag which gave me the conclusion listed above maybe I'm supposed to use another compiler (or maybe i needed more flags than just that)
 Mixing C++ and D DLLs should work. If you're statically linking 
 the DLL, which requires import libraries on Windows, you might 
 have the above issue.
I assumed so that it SHOULD work, as i found multiple documents online talking about using them together but non specifying if there should be special stuff you would have to do on making dlls that mix them.... As well I only intended to use shared libraries not static ones... I did see a lot of stuff talking about loading the dlls from some special code you would place in your app to load them manually which gave me concerns maybe using .lib files were not possible between the langs -> Which prompted me to come here for help as a last resort.
Jul 01 2017
next sibling parent reply Damien Gibson <spiceywolf.archaicsoft outlook.com> writes:
Well I finally somehow got it to stop complaining about a bad lib 
file, but now it wants to tell me the entry point for the 
functions i list isnt correct, so now im just unsure if its being 
stupid on me or im not writing something write on the D or C++ 
end...

The D code:
_______________________________________________________________
import std.stdio;

export:

void ConsoleWrite()
{
	writeln("This is a test written in DLang/DMD!");
}

void ConsoleWait()
{
	readln();
}
_______________________________________________________________

i imported the stuff on CPP and tried to call it.. this is the 
hpp file:

myclass.hpp:
_______________________________________________________________
#pragma once

#ifdef _MYDLL_EXPORTS
	#define DllAPI __declspec(dllexport)
#else
	#define DllAPI __declspec(dllimport)
#endif

DllAPI void ConsoleWrite();
DllAPI void ConsoleWait();
_______________________________________________________________

The errors:

_______________________________________________________________
2 error LNK1120: 1 unresolved externals
1 error LNK2019: unresolved external symbol 
"__declspec(dllimport) void __cdecl ConsoleWrite (void)" 
(__imp_?ConsoleWrite myclass  SAXXZ) referenced in function _wmain
_______________________________________________________________
Jul 01 2017
parent reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Saturday, 1 July 2017 at 20:47:55 UTC, Damien Gibson wrote:
 Well I finally somehow got it to stop complaining about a bad 
 lib file, but now it wants to tell me the entry point for the 
 functions i list isnt correct, so now im just unsure if its 
 being stupid on me or im not writing something write on the D 
 or C++ end...

 The D code:
 _______________________________________________________________
 import std.stdio;

 export:

 void ConsoleWrite()
 {
 	writeln("This is a test written in DLang/DMD!");
 }

 void ConsoleWait()
 {
 	readln();
 }
 _______________________________________________________________

 i imported the stuff on CPP and tried to call it.. this is the 
 hpp file:

 myclass.hpp:
 _______________________________________________________________
 #pragma once

 #ifdef _MYDLL_EXPORTS
 	#define DllAPI __declspec(dllexport)
 #else
 	#define DllAPI __declspec(dllimport)
 #endif

 DllAPI void ConsoleWrite();
 DllAPI void ConsoleWait();
 _______________________________________________________________

 The errors:

 _______________________________________________________________
 2 error LNK1120: 1 unresolved externals
 1 error LNK2019: unresolved external symbol 
 "__declspec(dllimport) void __cdecl ConsoleWrite (void)" 
 (__imp_?ConsoleWrite myclass  SAXXZ) referenced in function 
 _wmain
 _______________________________________________________________
If you're wanting to use the names (e.g. "ConsoleWrite") as is on the C++ side them you need to declare them extern(C++) ( or extern(C)) on the D side. if you were to run whatever the equivalent of "nm my.dll | grep Console" on windows on the dll then you'd see the two symbols with a different name (i.e. not __imp_?ConsoleWrite myclass SAXXZ).
Jul 01 2017
next sibling parent Damien Gibson <spiceywolf.archaicsoft outlook.com> writes:
 If you're wanting to use the names (e.g. "ConsoleWrite") as is 
 on the C++ side them you need to declare them extern(C++) ( or 
 extern(C)) on the D side. if you were to run whatever the 
 equivalent of "nm my.dll | grep Console" on windows on the dll 
 then you'd see the two symbols with a different name (i.e. not 
 __imp_?ConsoleWrite myclass  SAXXZ).
Thanks for the reply. Ive generated one using the extern(C) tag now, and checked it in Depends.exe(Dependency Walker) it now shows the Entry Point names as the correct names which is good news i really appreciate that. Its progress! Though i still retain the errors when trying to run it with C++.
Jul 01 2017
prev sibling next sibling parent Damien Gibson <spiceywolf.archaicsoft outlook.com> writes:
Well I ended up getting it to compile finally by adding extern 
"C" before the function imports on C++ side (Again i added the 
extern(C) to D side) however i still end up not being able to run 
the program as it keeps telling me:

0xC0000005: Access violation reading location 0x00000000

Ive been googling this for a while but can't seem to figure out 
what causes it aside from the general concensus being "Im trying 
to access a null pointer" but neither side of my code as far as i 
can tell actually attempts this... any ideas?
Jul 01 2017
prev sibling parent reply Damien Gibson <spiceywolf.archaicsoft outlook.com> writes:
K im retarded... So I forgot the golden rule, debug libs with 
debug app, release libs with release app.. I attempted loading 
the debug version of dll with D again just to see what kinda 
errors (may) come up there, sure enough there is and i get a 
fairly detailed one... However, when the function ConsoleWrite is 
called in either project, it goes back to the close bracket on 
the myclass.d page(The original myclass.d from the actual dll 
source code) and then re[prts stdio.d "in gc_malloc"

At this point I am thoroughly confused... It has only done this 
since adding the extern(C) tag to the source... even changing 
that to C++(Where depends.exe reports a garbled mess of a name 
again) still reports the same issue.
Jul 01 2017
parent reply Nicholas Wilson <iamthewilsonator hotmail.com> writes:
On Sunday, 2 July 2017 at 05:33:45 UTC, Damien Gibson wrote:
 K im retarded... So I forgot the golden rule, debug libs with 
 debug app, release libs with release app.. I attempted loading 
 the debug version of dll with D again just to see what kinda 
 errors (may) come up there, sure enough there is and i get a 
 fairly detailed one... However, when the function ConsoleWrite 
 is called in either project, it goes back to the close bracket 
 on the myclass.d page(The original myclass.d from the actual 
 dll source code) and then re[prts stdio.d "in gc_malloc"
Ahh, you need to initialise the D runtime before you call any functions that depend on it (e.g. ones that interact with the file system). declare extern "C" int rt_init(); in your c++ code and call it before ConsoleWrite and it should work.
 At this point I am thoroughly confused... It has only done this 
 since adding the extern(C) tag to the source... even changing 
 that to C++(Where depends.exe reports a garbled mess of a name 
 again) still reports the same issue.
That "garbled mess" is the microsoft C++ mangling of the symbol, its supposed to look like that.
Jul 01 2017
parent Damien Gibson <spiceywolf.archaicsoft outlook.com> writes:
 Ahh, you need to initialise the D runtime before you call any 
 functions that depend on it (e.g. ones that interact with the 
 file system).

 declare
     extern "C" int rt_init();
 in your c++ code and call it before ConsoleWrite and it should 
 work.
Honestly i did try this and it didnt correct the problem... HOWEVER... I had been deleting the dll page VS and Xamarin always generate with a shared dll project as since i got dlls working with D in the first place(I was slow to figure it out) it worked just fine without the dllmain page they generated... Placing that back in there now that weve come this far corrected the problem-> Without the need to even write rt_init in D or C++. Thank you both very much for the help and information you guys have provided this problem is finally solved! ___________________________________________________________________________________ IF anyone happens to come across this thread in the future and has the same problem i did -> Note: Probably involving the use of Xamarin/MonoDevelop or Visual Studio with dll creation or compatibility with C++ I'd be happy to create a couple of sample projects and list the stuff it required me to install for it all to work. I'm not going to do that at this moment as since I had to ask it seems i MAY be the only moron who seemed to have this issue? Anyway Bye everyone!
Jul 02 2017
prev sibling parent Jacob Carlborg <doob me.com> writes:
On 2017-07-01 21:11, Damien Gibson wrote:

 As well I only intended to use shared libraries not static ones...
Well, you can use shared libraries in two different way, dynamic linking or dynamic loading. Dynamic linking is when you declare your external symbols as usual and you link with the shared library at build time. Dynamic loading is when you declared your external symbols as function pointer and you don't link with the shared libraries at build time. You then use "dlopen" and the family of functions on Posix and "LoadLibrary" on Windows to load the shared library at runtime. When using dynamic linking on Posix you link directly with the shared library. When using dynamic linking on Windows you don't link directly with the shared library but instead link with an import library, which is basically a static library (as far as I understand). I would assume that this import library has the same problem as any other static library. When using dynamic loading you don't have to worry about these different formats at all. You can read more about static linking vs dynamic linking vs dynamic loading and about the problems with the different formats in the dlang blog [1] and here [2]. [1] http://dlang.org/blog/2017/06/26/project-highlight-derelict/ [2] http://derelictorg.github.io/bindings/ -- /Jacob Carlborg
Jul 02 2017