www.digitalmars.com         C & C++   DMDScript  

digitalmars.D - DLL, export bool dfunc(char[] s, extern (Windows) bool function()

reply Bjoern <nanali nospam-wanadoo.fr> writes:
Subject; DLL function calls callback function in callee (parent)

like
// MyDLL a Dll written in D
export bool dfunc(char[] s,extern (Windows)char[] function() cb)
{
    while ( char[] t = tokenize(s)) cb(t);
    return true;
}

I have to use some 4GL code to explain:


FUNCTION GetResult(StringToAnanlyse is string = "Hello from 4GL")
// Call dfunc , pass StringToAnalyse, and address of CallBack Function
   IF API("MyDLL", "dfunc", StringToAnanlyse, &ReceiveResult)
   END

// The CallBack Function
PRIVATE FUNCTION ReceiveResult(token is string)
   WHILE token <> ""
     Trace(token)
     newString += (token + ",") // defined elsewhere
   END
   RESULT newString
// Output
Hello
from
4GL
newString == "Hello,from,4GL,"
---------------------------------------------------
I ask here instead of D.lean because I mean the official "DLLs in D" 
documents should explain this functionality too.

Oh, the question :)

export bool dfunc(char[] s, extern (Windows) char[] function() cb)

I think at least my intention is clear , so I hope somebody is willing 
to  show me how to implement such a DLL function.

Many thanks in advance, Bjoern
Jan 15 2008
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Bjoern" <nanali nospam-wanadoo.fr> wrote in message 
news:fmiien$14cf$1 digitalmars.com...

 export bool dfunc(char[] s, extern (Windows) char[] function() cb)

 I think at least my intention is clear , so I hope somebody is willing to 
 show me how to implement such a DLL function.

I'm guessing that 4GL expects DLL functions to use either C or Windows calling conventions. Secondly AFAIK there's no way to indicate the calling convention of a function pointer inline; it has to be done as an alias/typedef and then used. alias extern(Windows) char[] function() MyFuncType; // Don't know if it's extern(C) or extern(Windows) extern(Windows) export bool dfunc(char[] s, MyFuncType cb) { ... }
Jan 15 2008
parent reply Bjoern <nanali nospam-wanadoo.fr> writes:
Jarrett Billingsley schrieb:
 I'm guessing that 4GL expects DLL functions to use either C or Windows 
 calling conventions.  Secondly AFAIK there's no way to indicate the calling 
 convention of a function pointer inline; it has to be done as an 
 alias/typedef and then used.
 
 alias extern(Windows) char[] function() MyFuncType;
 
 // Don't know if it's extern(C) or extern(Windows)
 extern(Windows) export bool dfunc(char[] s, MyFuncType cb)
 {
     ...
 } 

Thanks Jarret!, yes the 4GL expects Windows calling convention. (and uses just the .DLL, no .LIB) Using an alias instead of inlining is okay, not to say smarter! In reality I have to use : alias extern(Windows) void function(char[] token, bool eof) MyFuncType; extern(Windows) export bool dfunc(char[] s, MyFuncType cb) { // do something and call cb, (exists in a secondary thread) cb(token, false) } I hope this is correct ? However, thanks to your help I should be able to solve the problem(s) :) by myself. Bjoern
Jan 15 2008
parent reply "Jarrett Billingsley" <kb3ctd2 yahoo.com> writes:
"Bjoern" <nanali nospam-wanadoo.fr> wrote in message 
news:fmja4s$11rq$1 digitalmars.com...

 alias extern(Windows) void function(char[] token, bool eof) MyFuncType;

 extern(Windows) export bool dfunc(char[] s, MyFuncType cb)
 {
   // do something and call cb, (exists in a secondary thread)
  cb(token, false)
 }
 I hope this is correct ?

That looks perfectly fine. Only thing I wonder is, does 4GL support D-style char[]? Or will it be passing/expecting C-style zero-terminated char*?
Jan 16 2008
next sibling parent Bjoern <nanali nospam-wanadoo.fr> writes:
Jarrett Billingsley schrieb:
 "Bjoern" <nanali nospam-wanadoo.fr> wrote in message 
 news:fmja4s$11rq$1 digitalmars.com...
 
 alias extern(Windows) void function(char[] token, bool eof) MyFuncType;

 extern(Windows) export bool dfunc(char[] s, MyFuncType cb)
 {
   // do something and call cb, (exists in a secondary thread)
  cb(token, false)
 }
 I hope this is correct ?

That looks perfectly fine. Only thing I wonder is, does 4GL support D-style char[]? Or will it be passing/expecting C-style zero-terminated char*?

Thanks for confirming Jarret, Yes it supports D style char with a little effort : MyString is string // dynamic ANSI string MyUTF8String = StringToUTF8(MyString) // toUTF16 et vice versa Heh, I still have to make tests :) But you are right, most probabely it is more economic to pass the string as pointer to C string. ( because this string could contain the contents of an complete D source file ;) ) Due to the fact that my tool is garbage collected too, passing a dynamic string's address is not secure because this address may change. A dynamic string can contain 2 GB. here (in theory ...), so using standard C string is most probabely what I have to choose. Let's see. Bjoern OT , in case that you are courious what 4GL I am using , here a link. You can download full working express copy . version 10, ( most current is 12) -- A 4GL + matrix - financial - statistic - array, dyn array, asso. array, runtime compiler,threads, outstanding GUI designer .... have fun. http://www.windev.com/windev/quick-overview-WD.html
Jan 16 2008
prev sibling parent Bjoern <nanali nospam-wanadoo.fr> writes:
// HERE I /most probabely/ can use char[]
alias extern(Windows) void function(char[] token, bool eof) MyFuncType;
// Here of course NOT !
extern(Windows) export bool dfunc(char* s, MyFuncType cb)
{
   char[] tok;
   // do something and call cb, (exists in a secondary thread)
   cb(tok, false);
}


Sorry. Next time, I'll think twice. Bjoern
Jan 17 2008