Pragma mangle and D shared objects

H. S. Teoh via Digitalmars-d-learn digitalmars-d-learn at puremagic.com
Sat Oct 25 08:07:48 PDT 2014


On Sat, Oct 25, 2014 at 09:20:33AM -0400, Etienne Cimon via Digitalmars-d-learn wrote:
> I haven't been able to find much about pragma mangle. I'd like to do
> the following:
> 
> http://forum.dlang.org/thread/hznsrmviciaeirqkjzpy@forum.dlang.org#post-zhxnqqubyudteycwudzz:40forum.dlang.org
> 
> The part I find ugly is this:
> 
> void* vp = dlsym(lib, "_D6plugin11getInstanceFZC2bc2Bc\0".ptr);
> 
> I want to write a framework that stores a dynamic library name and
> symbol to execute, and downloads the dynamic library if it's not
> available. This would be in a long-running server/networking
> application, and needs to be simple to use.

Perhaps the .mangleof built-in property might help you here? For
instance:

	---plugin.d---
	class MyClass;
	MyClass getInstance();

	---test.d---
	import std.stdio;
	import plugin;

	void main() {
		writeln(plugin.getInstance.mangleof);
	}

Output:

	_D6plugin11getInstanceFZC6plugin7MyClass

Granted, it's a bit ugly (you have to actually create a module called
'plugin' in order to get the right mangling), but at least it doesn't
require the user to learn how D's mangling scheme works. You just write
a function prototype for the function you're trying to lookup, and call
.mangleof on it.


> The mangling makes it less obvious for the programmer writing a
> plugin. Does mangle make it possible to change this to dlsym(lib,
> "myOwnMangledName"), or would it still have strange symbols?
[...]

What you *could* do, is to use .mangleof and clever regex'ing to make it
possible to do that. For example, something along these lines:

	---dl_support.d---
	alias ReturnType = ... /* whatever type you want */;
	private ReturnType pluginFuncStubName(... /* arguments here */);

	auto loadPluginFunction(string library, string funcName) {
		auto r = regex(`pluginFuncStubName`);
		auto mangledName =
			pluginFuncStubName.mangleof.replace(r, funcName);
		...
		/* mangledName should now be the mangled string you need
		 * to find the symbol */
	}

Basically, use an unambiguous blatantly long name for your function
prototype, and do a search-and-replace to substitute that with the
desired function name.

Note that you still need to have a separate stub per function signature;
so if you want users to be able to load functions of arbitrary
signature, you probably need to make that a template parameter and have
the user pass in the desired function signature. For example:

	auto loadPluginFunction(Signature)(string library, string funcName)
	{
		import std.traits : ReturnType, ParameterTypeTuple;
		import std.regex : regex, replaceFirst;
	
		// Declare a static function with the user-desired
		// signature, with a nicely-substitutable name
		static ReturnType!Signature
			pluginFuncStubName(ParameterTypeTuple!Signature);
		auto r = regex(`pluginFuncStubName`);
		auto symbol = pluginFuncStubName.mangleof.replaceFirst(r, funcName);
	
		// Proof of concept
		import std.stdio;
		writeln(symbol);
	
		// ... Call dlsym to find function here
	
		// Just to make this compile, replace with real function pointer in
		// your code here.
		return null;
	}
	
	void main() {
		auto f1 = loadPluginFunction!(int function(string,int))("mylib", "func1");
		auto f2 = loadPluginFunction!(void function(float))("mylib", "func2");
	}

Output:

	_D4test33__T18loadPluginFunctionTPFAyaiZiZ18loadPluginFunctionFAyaAyaZ18func1FAyaiZi
	_D4test30__T18loadPluginFunctionTPFfZvZ18loadPluginFunctionFAyaAyaZ18func2FfZv

This example isn't complete yet (you need to do something about the
"loadPluginFunction" component in the mangled name), but you should be
able to work out a way of producing the correct mangled name from here.
But at least it demonstrates how you can have a very nice API for your
users -- they just pass in the function prototype of the function they
want, and the library code takes care of deriving the correct mangled
names.

Hope this helps.


T

-- 
Just because you can, doesn't mean you should.


More information about the Digitalmars-d-learn mailing list