www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to use a function without their sources

reply Jordi Sayol <g.sayol yahoo.es> writes:
Is there a way to use a function from a static D library without importing
their D sources nor their DI interface?
-- 
Jordi Sayol
Jan 18 2013
next sibling parent "Rob T" <alanb ucora.com> writes:
On Friday, 18 January 2013 at 17:02:51 UTC, Jordi Sayol wrote:
 Is there a way to use a function from a static D library 
 without importing their D sources nor their DI interface?
Yes you should be able to do it, but not everything can be imported without the source code, for example function templates are not included in the library object file unless you make the effort to wrap them into specific typed versions that will be compiled into the object file. If you don't have a di file for the library, you can always make one. See this related thread which is basically the same subject http://forum.dlang.org/thread/jhmgqvvlyrunleknkaxz forum.dlang.org --rt
Jan 18 2013
prev sibling parent reply "nazriel" <spam dzfl.pl> writes:
On Friday, 18 January 2013 at 17:02:51 UTC, Jordi Sayol wrote:
 Is there a way to use a function from a static D library 
 without importing their D sources nor their DI interface?
lib.d: extern(C) void printf(const char*, ...); void foo() { printf("%s".ptr, "hi".ptr); } test.d: extern(C) void _D3lib3fooFZv(); void main() { _D3lib3fooFZv(); } Hehe. Now, to be honest that is a good question. How to handle name mangling? Maybe pragma(mangleOf, "") by Alex Petterson could help.
Jan 18 2013
next sibling parent reply "Maxim Fomin" <maxim maxim-fomin.ru> writes:
On Friday, 18 January 2013 at 17:47:42 UTC, nazriel wrote:
 On Friday, 18 January 2013 at 17:02:51 UTC, Jordi Sayol wrote:
 Is there a way to use a function from a static D library 
 without importing their D sources nor their DI interface?
lib.d: extern(C) void printf(const char*, ...); void foo() { printf("%s".ptr, "hi".ptr); } test.d: extern(C) void _D3lib3fooFZv(); void main() { _D3lib3fooFZv(); } Hehe. Now, to be honest that is a good question. How to handle name mangling? Maybe pragma(mangleOf, "") by Alex Petterson could help.
----lib.d---- extern(C) void printf(const char*, ...); extern(C) void foo() { printf("%s\n".ptr, "hi".ptr); } ----main.d---- extern extern(C) void foo(); void main() { foo(); } -------------- # dmd mylib.d -lib -oflibmylib.a # dmd main.d -L-lmylib -L-L. This is possible if inside library non-member functions are marked as extern(C). Otherwise a .di file is needed.
Jan 18 2013
parent reply "nazriel" <spam dzfl.pl> writes:
On Friday, 18 January 2013 at 18:10:35 UTC, Maxim Fomin wrote:
 On Friday, 18 January 2013 at 17:47:42 UTC, nazriel wrote:
 On Friday, 18 January 2013 at 17:02:51 UTC, Jordi Sayol wrote:
 Is there a way to use a function from a static D library 
 without importing their D sources nor their DI interface?
lib.d: extern(C) void printf(const char*, ...); void foo() { printf("%s".ptr, "hi".ptr); } test.d: extern(C) void _D3lib3fooFZv(); void main() { _D3lib3fooFZv(); } Hehe. Now, to be honest that is a good question. How to handle name mangling? Maybe pragma(mangleOf, "") by Alex Petterson could help.
----lib.d---- extern(C) void printf(const char*, ...); extern(C) void foo() { printf("%s\n".ptr, "hi".ptr); } ----main.d---- extern extern(C) void foo(); void main() { foo(); } -------------- # dmd mylib.d -lib -oflibmylib.a # dmd main.d -L-lmylib -L-L. This is possible if inside library non-member functions are marked as extern(C). Otherwise a .di file is needed.
Nice! This should be mentioned at Language Reference, so it won't get lost.
Jan 18 2013
parent reply Johannes Pfau <nospam example.com> writes:
Am Fri, 18 Jan 2013 19:17:33 +0100
schrieb "nazriel" <spam dzfl.pl>:

 [...]
 
 Nice!
 This should be mentioned at Language Reference, so it won't get 
 lost.
 
Isn't this documented? I thought it was well known that you can mark D functions as extern(C). It's needed when implementing callback functions for C, for example. You also get all the problems of unmangled C names, I remember some nice segfaults in Derelict related to this (fixed some time ago in derelict.)
Jan 18 2013
parent "nazriel" <spam dzfl.pl> writes:
On Friday, 18 January 2013 at 18:23:03 UTC, Johannes Pfau wrote:
 Am Fri, 18 Jan 2013 19:17:33 +0100
 schrieb "nazriel" <spam dzfl.pl>:

 [...]
 
 Nice!
 This should be mentioned at Language Reference, so it won't 
 get lost.
 
Isn't this documented? I thought it was well known that you can mark D functions as extern(C). It's needed when implementing callback functions for C, for example.
I mean, some kind of pointer how to achieve such thing (Question in first post). To be honest, I did think that there is some other way than using extern (C) way.
 You also get all the problems of unmangled C names, I remember 
 some
 nice segfaults in Derelict related to this (fixed some time ago 
 in
 derelict.)
Jan 18 2013
prev sibling next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 1/18/13, nazriel <spam dzfl.pl> wrote:
 extern(C) void _D3lib3fooFZv();

 void main() {
 	_D3lib3fooFZv();
 }
That's a *terrible* idea, you are calling a D function using the C convention, you're going to have all sorts of problems. extern(D) is not just used for mangling, it's also used for designating how parameters are passed to and results are returned from a function (via stack/registers). E.g.: import std.stdio; int foo(int x, int y) { return x + y; } alias extern(C) int function(int, int) Func; void main() { Func func = cast(Func)&foo; writeln(func(1, 2)); } $ rdmd test.d
 object.Error: Access Violation
Jan 18 2013
parent reply "nazriel" <spam dzfl.pl> writes:
On Friday, 18 January 2013 at 18:18:07 UTC, Andrej Mitrovic wrote:
 On 1/18/13, nazriel <spam dzfl.pl> wrote:
 extern(C) void _D3lib3fooFZv();

 void main() {
 	_D3lib3fooFZv();
 }
That's a *terrible* idea, you are calling a D function using the C convention, you're going to have all sorts of problems. extern(D) is not just used for mangling, it's also used for designating how parameters are passed to and results are returned from a function (via stack/registers). E.g.:
Oh really? Thanks, I didn't know.
Jan 18 2013
parent reply "nazriel" <spam dzfl.pl> writes:
On Friday, 18 January 2013 at 18:23:57 UTC, nazriel wrote:
 On Friday, 18 January 2013 at 18:18:07 UTC, Andrej Mitrovic 
 wrote:
 On 1/18/13, nazriel <spam dzfl.pl> wrote:
 extern(C) void _D3lib3fooFZv();

 void main() {
 	_D3lib3fooFZv();
 }
That's a *terrible* idea, you are calling a D function using the C convention, you're going to have all sorts of problems. extern(D) is not just used for mangling, it's also used for designating how parameters are passed to and results are returned from a function (via stack/registers). E.g.:
Oh really? Thanks, I didn't know.
As a disclaimer, I did know about this. I wasn't serious by posting this example. So don't take this serious. I just used objdump to get mangled name. ^^
Jan 18 2013
parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 1/18/13, nazriel <spam dzfl.pl> wrote:
 So don't take this serious.
This is D.learn, so people expect to get valid information here and they don't know if you're showing an invalid example or not unless you tell them.
Jan 18 2013
parent reply "nazriel" <spam dzfl.pl> writes:
On Friday, 18 January 2013 at 18:44:29 UTC, Andrej Mitrovic wrote:
 On 1/18/13, nazriel <spam dzfl.pl> wrote:
 So don't take this serious.
This is D.learn, so people expect to get valid information here and they don't know if you're showing an invalid example or not unless you tell them.
It's valid example as long as you objump object file. Show me a working solution to question from first post. "How to use existing static D library *WITHOUT* using .DI files". You can't edit library itself, so adding extern(C) to functions won't work. You can't create .DI file - which is the main question from first post.
Jan 18 2013
next sibling parent "anonymous" <anonymous example.com> writes:
On Friday, 18 January 2013 at 17:47:42 UTC, nazriel wrote:
 lib.d:

 extern(C) void printf(const char*, ...);

 void foo() {
 	printf("%s".ptr, "hi".ptr);	
 }

 test.d:

 extern(C) void _D3lib3fooFZv();

 void main() {
 	_D3lib3fooFZv();
 }
On Friday, 18 January 2013 at 18:18:07 UTC, Andrej Mitrovic wrote:
 That's a *terrible* idea, you are calling a D function using 
 the C
 convention, you're going to have all sorts of problems. 
 extern(D) is
 not just used for mangling, it's also used for designating how
 parameters are passed to and results are returned from a 
 function (via
 stack/registers).
On Friday, 18 January 2013 at 18:50:01 UTC, nazriel wrote:
 It's valid example as long as you objump object file.
It's a bad example. You just got lucky in that the calling conventions match in that particular case.
Jan 18 2013
prev sibling next sibling parent reply Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 1/18/13, nazriel <spam dzfl.pl> wrote:
 Show me a working solution to question from first post.

 "How to use existing static D library *WITHOUT* using .DI files".
 You can't edit library itself, so adding extern(C) to functions
 won't work.
 You can't create .DI file - which is the main question from first
 post.
That formulation makes no sense. If it's not his library the provider will either give the .d files or autogenerated/handwritten .di files. He won't just get a naked static library without supporting files. And if he controls the library, he will either have to autogenerate .di files, or handwrite them. Even if he uses extern(C) he will still have to provide a .d file with all extern(C) functions and types.
Jan 18 2013
parent reply "nazriel" <spam dzfl.pl> writes:
On Friday, 18 January 2013 at 20:33:04 UTC, Andrej Mitrovic wrote:
 On 1/18/13, nazriel <spam dzfl.pl> wrote:
 Show me a working solution to question from first post.

 "How to use existing static D library *WITHOUT* using .DI 
 files".
 You can't edit library itself, so adding extern(C) to functions
 won't work.
 You can't create .DI file - which is the main question from 
 first
 post.
That formulation makes no sense. If it's not his library the provider will either give the .d files or autogenerated/handwritten .di files. He won't just get a naked static library without supporting files. And if he controls the library, he will either have to autogenerate .di files, or handwrite them. Even if he uses extern(C) he will still have to provide a .d file with all extern(C) functions and types.
Still doesn't answers question from first post. So let me quote it for you: "Is there a way to use a function from a static D library without importing their D sources nor their DI interface?" There were 2 types of answers in this topic: 1) Yes, you can if functions in library are marked as extern(C) 2) Yes, you can even if functions are not marked as extern(C) with little hack which is dumping object file. Whatever you think it is *terrible* idea or not, it seems to be the only one working idea in this, specific scenario.
Jan 18 2013
parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 1/18/13, nazriel <spam dzfl.pl> wrote:
 There were 2 types of answers in this topic:
 1) Yes, you can if functions in library are marked as extern(C)
You still have to provide .d or .di files, you can't expect the user to have to manually write extern declarations.
 2) Yes, you can even if functions are not marked as extern(C)
 with little hack which is dumping object file.
That little hack is not very reliable. And once Pull 1085 is merged that technique will become completely unreliable. (https://github.com/D-Programming-Language/dmd/pull/1085).
 Whatever you think it is *terrible* idea or not, it seems to be
 the only one working idea in this, specific scenario.
The terrible idea is using the mangled representation of a D function but calling it as an extern(C) function. This will simply not work properly. Using extern(C) properly is fine, of course. However even that is problematic because extern(C) does not allow you to overload functions and you'll have 64bit breakage due to http://d.puremagic.com/issues/show_bug.cgi?id=5570.
Jan 18 2013
prev sibling next sibling parent Jordi Sayol <g.sayol yahoo.es> writes:
Al 18/01/13 21:32, En/na Andrej Mitrovic ha escrit:
 On 1/18/13, nazriel <spam dzfl.pl> wrote:
 Show me a working solution to question from first post.

 "How to use existing static D library *WITHOUT* using .DI files".
 You can't edit library itself, so adding extern(C) to functions
 won't work.
 You can't create .DI file - which is the main question from first
 post.
That formulation makes no sense. If it's not his library the provider will either give the .d files or autogenerated/handwritten .di files. He won't just get a naked static library without supporting files. And if he controls the library, he will either have to autogenerate .di files, or handwrite them. Even if he uses extern(C) he will still have to provide a .d file with all extern(C) functions and types.
Thank you for your answer. What's the sense for extern(D)? and in which case is useful. -- Jordi Sayol
Jan 20 2013
prev sibling parent Andrej Mitrovic <andrej.mitrovich gmail.com> writes:
On 1/20/13, Jordi Sayol <g.sayol yahoo.es> wrote:
 Thank you for your answer.
 What's the sense for extern(D)? and in which case is useful.
extern(D) is the default linkage for all functions. D has its own linkage by default. The reason why is probably to allow the compiler to optimize the way the functions are called without breaking compatibility with C.
Jan 20 2013
prev sibling next sibling parent Johannes Pfau <nospam example.com> writes:
Am Fri, 18 Jan 2013 18:47:41 +0100
schrieb "nazriel" <spam dzfl.pl>:

 lib.d:
 void foo() {
 	printf("%s".ptr, "hi".ptr);	
 }
 
 test.d:
 extern(C) void _D3lib3fooFZv();
 
I think this is dangerous, there's no guarantee that extern(D) equals extern(C).
 How to handle name 
 mangling?
 Maybe pragma(mangleOf, "") by Alex Petterson could help.
extern(D) + pragma(mangleOf) could work. But it's probably simpler and safer to just write a .di file for that function manually: lib.di: module lib; void foo();
Jan 18 2013
prev sibling parent reply Jordi Sayol <g.sayol yahoo.es> writes:
Al 18/01/13 18:47, En/na nazriel ha escrit:
 On Friday, 18 January 2013 at 17:02:51 UTC, Jordi Sayol wrote:
 Is there a way to use a function from a static D library without importing
their D sources nor their DI interface?
lib.d: extern(C) void printf(const char*, ...); void foo() { printf("%s".ptr, "hi".ptr); } test.d: extern(C) void _D3lib3fooFZv(); void main() { _D3lib3fooFZv(); } Hehe. Now, to be honest that is a good question. How to handle name mangling? Maybe pragma(mangleOf, "") by Alex Petterson could help.
Thanks! Why it works with "extern(C)", but not works with "extern(D)"? -- Jordi Sayol
Jan 18 2013
parent "nazriel" <spam dzfl.pl> writes:
On Friday, 18 January 2013 at 18:34:24 UTC, Jordi Sayol wrote:
 Al 18/01/13 18:47, En/na nazriel ha escrit:
 On Friday, 18 January 2013 at 17:02:51 UTC, Jordi Sayol wrote:
 Is there a way to use a function from a static D library 
 without importing their D sources nor their DI interface?
lib.d: extern(C) void printf(const char*, ...); void foo() { printf("%s".ptr, "hi".ptr); } test.d: extern(C) void _D3lib3fooFZv(); void main() { _D3lib3fooFZv(); } Hehe. Now, to be honest that is a good question. How to handle name mangling? Maybe pragma(mangleOf, "") by Alex Petterson could help.
Thanks! Why it works with "extern(C)", but not works with "extern(D)"?
I shouldn't paste this code in first place. As far as I know and other folks mentioned there is no "clean" way to call function from D library without using .DI files or marking function in library as extern (C). You can always look up symbol table like I did for this example. Summary: If you write library - you can mark function as extern (C) to call it later from other app without .DI fil. You need to create .DI file if you use someone else library.
Jan 18 2013