www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - using d dll/lib with msvc program

reply "crashtua" <crashtua gmail.com> writes:
Is it possible to build dll or lib with dmc to use it in program 
builded in microsoft c++ compiler?
May 13 2012
parent reply "Froglegs" <lugtug yahoo.com> writes:
On Sunday, 13 May 2012 at 19:07:41 UTC, crashtua wrote:
 Is it possible to build dll or lib with dmc to use it in 
 program builded in microsoft c++ compiler?
Yes you can download Visual D, build a D DLL with DMD, and call it from a Visual C++ program. Unfortunately you have to use C to communicate between them, and the D IDE experience is pretty bad. -this forum likes to reject posts with nonsense errors... btw
May 13 2012
parent reply "crashtua" <crashtua gmail.com> writes:
And how to load that dll? I have dll:
module dllmain;
import std.c.windows.windows;
import core.sys.windows.dll;
__gshared HINSTANCE g_hInst;
extern (Windows)
BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID 
pvReserved)
{
     final switch (ulReason)
     {
	case DLL_PROCESS_ATTACH:
	    g_hInst = hInstance;
	    dll_process_attach( hInstance, true );
	    break;

	case DLL_PROCESS_DETACH:
	    dll_process_detach( hInstance, true );
	    break;

	case DLL_THREAD_ATTACH:
	    dll_thread_attach( true, true );
	    break;

	case DLL_THREAD_DETACH:
	    dll_thread_detach( true, true );
	    break;
     }
     return true;
}
extern (C) int trololo(){return 10;}
Than try to load it:
	HINSTANCE LoadME;
	LoadME = LoadLibrary(L"C:\\Users\\CrashTUA\\Documents\\visual 
studio 
2010\\Projects\\DynamicLib1\\DynamicLib1\\Release\\DynamicLib1.dll");
	func dllprintt;
	dllprintt = (func)GetProcAddress(LoadME,"trololo");
	int i = dllprintt();
	return 0;
And it gives me acces violation...
May 13 2012
next sibling parent reply "Froglegs" <lugtug yahoo.com> writes:
 	HINSTANCE LoadME;
 	LoadME = LoadLibrary(L"C:\\Users\\CrashTUA\\Documents\\visual 
 studio 
 2010\\Projects\\DynamicLib1\\DynamicLib1\\Release\\DynamicLib1.dll");
 	func dllprintt;
 	dllprintt = (func)GetProcAddress(LoadME,"trololo");
 	int i = dllprintt();
 	return 0;
 And it gives me acces violation...
Well did LoadLibrary or did GetProcAddress fail?
May 13 2012
parent reply "crashtua" <crashtua gmail.com> writes:
LoadLibrary returns 100000(maybe wrong number of zeros,i dont
remember exactly:)). And GetProcAddress returns 0, so dllprintt
fails:(
May 14 2012
parent reply "crashtua" <crashtua gmail.com> writes:
So, thanks to all. It works after adding 'export' keyword and '_' 
symbol before function name.
May 14 2012
parent reply "crashtua" <crashtua gmail.com> writes:
But it is something strange, one function need '_' and another 
dont:(
In D dll i have:

extern (C) int function() f;
alias typeof(f) myfunc;

export extern (C) int retten()
{
	return 10;
}
export extern (C) void setf(myfunc ff)
{
	f=ff;
}
export extern (C) int ret()
{
	return f();
}

In C code:

int(*retten)() = (int (*)())GetProcAddress(dLib,"_retten");
int(*ret)() = (int (*)())GetProcAddress(dLib,"ret");
void(*setf)(int(*)()) = (void 
(*)(int(*)()))GetProcAddress(dLib,"setf");

Why so strange?
May 14 2012
parent Rainer Schuetze <r.sagitario gmx.de> writes:
On 5/14/2012 7:59 PM, crashtua wrote:
 But it is something strange, one function need '_' and another dont:(
 In D dll i have:

 extern (C) int function() f;
 alias typeof(f) myfunc;

 export extern (C) int retten()
 {
 return 10;
 }
 export extern (C) void setf(myfunc ff)
 {
 f=ff;
 }
 export extern (C) int ret()
 {
 return f();
 }

 In C code:

 int(*retten)() = (int (*)())GetProcAddress(dLib,"_retten");
 int(*ret)() = (int (*)())GetProcAddress(dLib,"ret");
 void(*setf)(int(*)()) = (void (*)(int(*)()))GetProcAddress(dLib,"setf");

 Why so strange?
I guess you are hitting this linker bug: http://d.puremagic.com/issues/show_bug.cgi?id=3956 A work around is to add the exports to the .def file.
May 14 2012
prev sibling parent reply Rainer Schuetze <r.sagitario gmx.de> writes:
On 5/14/2012 5:44 AM, crashtua wrote:
 And how to load that dll? I have dll:
 module dllmain;
 import std.c.windows.windows;
 import core.sys.windows.dll;
 __gshared HINSTANCE g_hInst;
 extern (Windows)
 BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved)
 {
 final switch (ulReason)
 {
 case DLL_PROCESS_ATTACH:
 g_hInst = hInstance;
 dll_process_attach( hInstance, true );
 break;

 case DLL_PROCESS_DETACH:
 dll_process_detach( hInstance, true );
 break;

 case DLL_THREAD_ATTACH:
 dll_thread_attach( true, true );
 break;

 case DLL_THREAD_DETACH:
 dll_thread_detach( true, true );
 break;
 }
 return true;
 }
 extern (C) int trololo(){return 10;}
add an "export" to the function: export extern (C) int trololo(){return 10;}
 Than try to load it:
 HINSTANCE LoadME;
 LoadME = LoadLibrary(L"C:\\Users\\CrashTUA\\Documents\\visual studio
 2010\\Projects\\DynamicLib1\\DynamicLib1\\Release\\DynamicLib1.dll");
 func dllprintt;
 dllprintt = (func)GetProcAddress(LoadME,"trololo");
The C calling convention prepends an underscore to the function name: dllprintt = (func)GetProcAddress(LoadME,"_trololo");
 int i = dllprintt();
 return 0;
 And it gives me acces violation...
May 13 2012
parent Manu <turkeyman gmail.com> writes:
On 14 May 2012 09:16, Rainer Schuetze <r.sagitario gmx.de> wrote:

 Than try to load it:
 HINSTANCE LoadME;
 LoadME = LoadLibrary(L"C:\\Users\\**CrashTUA\\Documents\\visual studio
 2010\\Projects\\DynamicLib1\\**DynamicLib1\\Release\\**DynamicLib1.dll");
 func dllprintt;
 dllprintt = (func)GetProcAddress(LoadME,"**trololo");
The C calling convention prepends an underscore to the function name: dllprintt = (func)GetProcAddress(LoadME,"_**trololo");
It seems GetProcAddress pulls that off for you. I thought that too, but it always workout without adding the _ for me.
May 14 2012