www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - Am I doing it wrong or is this a bug ?

reply Ezneh <petitv.isat gmail.com> writes:
Hello !

I'm doing some tests with the DLL example which is in the samples directory but
I have some problem with it.


Well, when I'm compiling the DLL with that files, I got no error and it works
in the test.d sample but doesn't work in another project (in another language) :

//mydll.d
module mydll;
import std.c.stdio;

export string dllprint() { return "hello"; }


//dll.d

import std.c.windows.windows;
import core.dll_helper;

__gshared HINSTANCE g_hInst;

extern (Windows)
BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved)
{
    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;
}

// .def file
LIBRARY "mydll.dll"
EXETYPE NT
SUBSYSTEM WINDOWS
CODE SHARED EXECUTE
DATA WRITE

// test.d
import mydll;
import std.stdio;

int main(string args[])
{
   writeln(mydll.dllprint());
   return 0;
}


With all theses files, test.exe works well.

But when I want to use it with another programming language, I got this error :

"Cannot find the entry point for 'dllprint' in 'mydll.dll'


So, I tried to change the .def file like this :

LIBRARY "mydll.dll"
EXETYPE NT
SUBSYSTEM WINDOWS
CODE SHARED EXECUTE
DATA WRITE
EXPORTS
	dllprint

but I got this error :

D:\D\dmd\samples\d\mydll>dmd -ofmydll.dll -L/IMPLIB mydll.d dll.d mydll.def
OPTLINK (R) for Win32  Release 8.00.2
Copyright (C) Digital Mars 1989-2009  All rights reserved.
http://www.digitalmars.com/ctg/optlink.html
OPTLINK : Error 180: No Match Found for Export/ENTRY -  : dllprint
OPTLINK : Error 81: Cannot EXPORT : dllprint


So what I'm doing wrong ? Is this a bug from optlink ?
Aug 12 2010
parent reply Don <nospam nospam.com> writes:
Ezneh wrote:
 Hello !
 
 I'm doing some tests with the DLL example which is in the samples directory
but I have some problem with it.
 
 
 Well, when I'm compiling the DLL with that files, I got no error and it works
in the test.d sample but doesn't work in another project (in another language) :
 
 //mydll.d
 module mydll;
 import std.c.stdio;
 
 export string dllprint() { return "hello"; }
 
 
 //dll.d
 
 import std.c.windows.windows;
 import core.dll_helper;
 
 __gshared HINSTANCE g_hInst;
 
 extern (Windows)
 BOOL DllMain(HINSTANCE hInstance, ULONG ulReason, LPVOID pvReserved)
 {
     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;
 }
 
 // .def file
 LIBRARY "mydll.dll"
 EXETYPE NT
 SUBSYSTEM WINDOWS
 CODE SHARED EXECUTE
 DATA WRITE
 
 // test.d
 import mydll;
 import std.stdio;
 
 int main(string args[])
 {
    writeln(mydll.dllprint());
    return 0;
 }
 
 
 With all theses files, test.exe works well.
 
 But when I want to use it with another programming language, I got this error :
 
 "Cannot find the entry point for 'dllprint' in 'mydll.dll'
 
 
 So, I tried to change the .def file like this :
 
 LIBRARY "mydll.dll"
 EXETYPE NT
 SUBSYSTEM WINDOWS
 CODE SHARED EXECUTE
 DATA WRITE
 EXPORTS
 	dllprint
 
 but I got this error :
 
 D:\D\dmd\samples\d\mydll>dmd -ofmydll.dll -L/IMPLIB mydll.d dll.d mydll.def
 OPTLINK (R) for Win32  Release 8.00.2
 Copyright (C) Digital Mars 1989-2009  All rights reserved.
 http://www.digitalmars.com/ctg/optlink.html
 OPTLINK : Error 180: No Match Found for Export/ENTRY -  : dllprint
 OPTLINK : Error 81: Cannot EXPORT : dllprint
 
 
 So what I'm doing wrong ? Is this a bug from optlink ?
You need to make dllprint an extern(C) function. If you just mark it as 'extern', it uses D name mangling, which the other language won't understand.
Aug 12 2010
next sibling parent Ezneh <petitv.isat gmail.com> writes:
Don Wrote:


 You need to make dllprint an extern(C) function. If you just mark it as 
 'extern', it uses D name mangling, which the other language won't 
 understand.
Seems to work with test.d but I got something like "AccessViolationException - Trying to access to a protected memory (read/write). This often means that the memory is corrupted" when I try to use it somewhere else. Well, I think I'm doing something wrong with that but I dunno what. Maybe I need a working dll example ...
Aug 12 2010
prev sibling parent reply Richard Webb <webby beardmouse.org.uk> writes:
Is returning a D string to a non-D language going to cause problems?
Aug 12 2010
parent reply Ezneh <petitv.isat gmail.com> writes:
Richard Webb Wrote:

 Is returning a D string to a non-D language going to cause problems?
Hmm it seems that returning an int works but returning string / char types doesn't work ... Anyone knows why ?
Aug 12 2010
next sibling parent Ezneh <petitv.isat gmail.com> writes:
Ezneh Wrote:

 Richard Webb Wrote:
 
 Is returning a D string to a non-D language going to cause problems?
Hmm it seems that returning an int works but returning string / char types doesn't work ... Anyone knows why ?
PS : "works" is kinda like "doesn't return an exception" but there's still something wrong with the DLL. //mydll.d module mydll; import std.stdio; extern (C) export int dllprint(int something) { return something^^something; } //test.d import mydll; import std.stdio; int main(string args[]) { writeln(mydll.dllprint(2)); return 0; } //Fine prints 4 But using it in .Net environment it prints "0" ...
Aug 12 2010
prev sibling parent reply Mafi <mafi example.org> writes:
Am 12.08.2010 15:59, schrieb Ezneh:
 Richard Webb Wrote:

 Is returning a D string to a non-D language going to cause problems?
Hmm it seems that returning an int works but returning string / char types doesn't work ... Anyone knows why ?
Hi, returning an int works because D's int and most other language's (eg C's) int are identical. D's string is an alias for 'immutable(char)[]'. The brackets [] idicate an D array. D arrays are not the same as C arrays. In C strings are char* pointing to a null terminated sequence of chars. In D they are more complicated. Just let your function return char* replace 'return xy;' with 'return toStringz(xy);'. Then put 'import std.string' at the begining of your file. Then you do this your function will return c-like strings for interfacing with C and C++.
Aug 12 2010
parent Ezneh <petitv.isat gmail.com> writes:
Mafi Wrote:

 Hi,
 returning an int works because D's int and most other language's (eg 
 C's) int are identical. D's string is an alias for 'immutable(char)[]'. 
 The brackets [] idicate an D array. D arrays are not the same as C 
 arrays. In C strings are char* pointing to a null terminated sequence of 
 chars. In D they are more complicated.
 Just let your function return char* replace 'return xy;' with 'return 
 toStringz(xy);'. Then put 'import std.string' at the begining of your 
 file. Then you do this your function will return c-like strings for 
 interfacing with C and C++.
Thanks ! It works well :-), and for integers (other message), I didn't replace the DLL so I got wrong value. I think I should learn phobos and druntime libraries before asking something like that. Ok, there's no problem now.
Aug 12 2010