www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - My is the order of parameters reversed for functions that are

reply David Nies <nies.david googlemail.com> writes:
Apparantly, the order in which parameters are passed to a 
dynamically loaded C function is reversed. See the following 
minimal example:

----------------
%> cat dll.c
#include "stdio.h"

int dll2(const char* first, const char* second) {
     printf("dll2() - first: '%s', second: '%s'\n", first, second);
     return 0;
}

int dll3(const char* first, const char* second, const char* 
third) {
     printf("dll3() - first: '%s', second: '%s', third: '%s'\n",
            first,
            second,
            third);
     return 0;
}
----------------

I compiled it with the following commands:

%> gcc -c dll.c -fpic
%> gcc -shared -o libdll.dyld dll.o
%> file libdll.dyld
libdll.dyld: Mach-O 64-bit dynamically linked shared library 
x86_64

Now, I'm using it with a very simple D program and see very 
unexpected results:

----------------
%> cat main.d
import std.stdio, std.string, core.sys.posix.dlfcn;

// extern functions
alias nothrow int function(const char*, const char*) dll2_fn;
alias nothrow int function(const char*, const char*, const char*) 
dll3_fn;

void main() {
     string sdlLibPath = "libdll.dyld";
     auto libraryHandle = dlopen(sdlLibPath.toStringz(), 
RTLD_LAZY);
     scope(exit) dlclose(libraryHandle);

     dll2_fn dll2 = cast(dll2_fn)dlsym(libraryHandle, "dll2");
     dll2("one", "two");

     dll3_fn dll3 = cast(dll3_fn)dlsym(libraryHandle, "dll3");
     dll3("one", "two", "three");
}

%> rdmd main.d
dll2() - first: 'two', second: 'one'
dll3() - first: 'three', second: 'two', third: 'one'
----------------

The order in which the C functions get the parameters is exactly 
the reverse order in which I supply them in D.

What is happening there? I also tried to export a function that 
has two different types from the C library. Calling it the same 
way from the client D program causes a segfault - which I'd 
expect when the parameters are really reversed.

How can I make sure the order is correct?
Nov 15 2015
parent reply David Nadlinger <code klickverbot.at> writes:
On Sunday, 15 November 2015 at 17:54:27 UTC, David Nies wrote:
 How can I make sure the order is correct?
Whenever you use a C function, it must be marked as, even if it's through a function pointer as in this case. Just apply the attribute to the dll2_fn and dll3_fn declarations. Hope this helps, David
Nov 15 2015
parent reply David Nies <nies.david googlemail.com> writes:
On Sunday, 15 November 2015 at 18:00:09 UTC, David Nadlinger 
wrote:
 On Sunday, 15 November 2015 at 17:54:27 UTC, David Nies wrote:
 How can I make sure the order is correct?
Whenever you use a C function, it must be marked as, even if it's through a function pointer as in this case. Just apply the attribute to the dll2_fn and dll3_fn declarations. Hope this helps, David
How do I mark it as such? Can you please give an example? Thanks for the quick reply! :)
Nov 15 2015
next sibling parent Andrea Fontana <nospam example.com> writes:
On Sunday, 15 November 2015 at 18:02:01 UTC, David Nies wrote:
 On Sunday, 15 November 2015 at 18:00:09 UTC, David Nadlinger 
 wrote:
 On Sunday, 15 November 2015 at 17:54:27 UTC, David Nies wrote:
 How can I make sure the order is correct?
Whenever you use a C function, it must be marked as, even if it's through a function pointer as in this case. Just apply the attribute to the dll2_fn and dll3_fn declarations. Hope this helps, David
How do I mark it as such? Can you please give an example? Thanks for the quick reply! :)
I think he refers to this: http://dlang.org/interfaceToC.html
Nov 15 2015
prev sibling parent reply David Nadlinger <code klickverbot.at> writes:
On Sunday, 15 November 2015 at 18:02:01 UTC, David Nies wrote:
 How do I mark it as such? Can you please give an example?

 Thanks for the quick reply! :)
Just add extern(C) to the beginning of the "alias" line. — David
Nov 15 2015
parent David Nies <nies.david googlemail.com> writes:
On Sunday, 15 November 2015 at 18:12:52 UTC, David Nadlinger 
wrote:
 On Sunday, 15 November 2015 at 18:02:01 UTC, David Nies wrote:
 How do I mark it as such? Can you please give an example?

 Thanks for the quick reply! :)
Just add extern(C) to the beginning of the "alias" line. — David
Great! Thanks to all of you! That was really quick and helpful!
Nov 15 2015