www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - Understanding behavior of member functions loaded at runtime

reply "Maeriden" <maeriden gmail.com> writes:
============================================================
module dll;

struct S
{
	int a;
	int b;
	
	int method()
	{
		return a + b;
	}
}

============================================================

module test;

import core.sys.posix.dlfcn;
import core.stdc.stdio;
import dll;
pragma(lib, "dl");

pragma(mangle, S.method.mangleof)
__gshared int function(S* self) paramMethod;

__gshared int function()        noparamMethod;

void main(string[] args)
{
	void* lib = dlopen("dll.so", RTLD_LAZY);
	
	string funcName = S.method.mangleof;
	noparamMethod = cast(typeof(noparamMethod)) dlsym(lib, 
funcName.ptr);
	paramMethod   = cast(typeof(paramMethod))   dlsym(lib, 
funcName.ptr);
	
	
	int result = noparamMethod();
	printf("%d\n", result);
	
	S s = { 1, 1 };
	result = paramMethod(&s);
	printf("%d\n", result);
	
	result = s.method(); // Symbol resolved because of pragma(mangle)
	printf("%d\n", result);
	
	// Error: function dll.S.method () is not callable using 
argument types (S*)
	//result = S.method(&s);
	//printf("%d\n", result);
}

============================================================

dmd -fPIC -shared -defaultlib=libphobos2.so dll.d
dmd -defaultlib=libphobos2.so -L-rpath=. test.d


the output is
0
2
Segmentation fault

My questions are
1) Why does 'noparamMethod" return 0?
I assume that 'this' points to S.init but how does it know where 
to find it? What's going on?

2) typeof(S.method) is "int()". Why's that? In C++ it would have 
been "int(S* const)" and I though in D it would have been 
"int(S*)"
2.1) Is this related to why case 4 doesn't compile?

3) Why does case 3 crash? I assume it's because there is no 
argument so 'this' is null, but wouldn't the call be translated 
to "S.method(&s)"?
Mar 17 2015
parent reply "Kagamin" <spam here.lot> writes:
You violate the ABI, try to use delegates instead of functions.
Mar 18 2015
parent reply "Maeriden" <maeriden gmail.com> writes:
On Wednesday, 18 March 2015 at 07:57:39 UTC, Kagamin wrote:
 You violate the ABI, try to use delegates instead of functions.
I'm sorry,I don't understand what you mean.
Mar 18 2015
parent =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 03/18/2015 09:02 AM, Maeriden wrote:
 On Wednesday, 18 March 2015 at 07:57:39 UTC, Kagamin wrote:
 You violate the ABI, try to use delegates instead of functions.
I'm sorry,I don't understand what you mean.
The types that you cast to are not correct. In D, callable member function pointers are delegates, a type that combines a function pointer and a context. import std.stdio; struct S { int a; int b; int method() { writeln(&a); return a + b; } } void main() { auto s = S(1, 1); auto func = &s.method; // <-- note lowercase s static assert ( is (typeof(func) == int delegate())); static assert (!is (typeof(func) == int function())); // <-- note ! assert(func() == 2); } The function pointer and the context pointer are available through the .funcptr and .ptr properties of the delegate. It is possible to make a delegate by setting those properties: void main() { auto s = S(1, 1); auto func = &S.method; // <-- note uppercase S static assert (!is (typeof(func) == int delegate())); // <-- note ! static assert ( is (typeof(func) == int function())); int delegate() d; // let's make a delegate d.funcptr = func; d.ptr = &s; assert(d() == 2); } Ali
Mar 18 2015