www.digitalmars.com         C & C++   DMDScript  

D - Dynamic function loading module

reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:
as D lacks the delphi extern 'foo.dll'
I've written (and now with 0.56 it works). a dynamic loading module.
the example on how to use loads the winmm.dll and allows you to use
timeBeginPeriod, etc.

hope someone else finds this useful.

there are some problems with templates that I've got to checkout, and it
would be good if there was a better way to write the templates.

Mike.



begin 666 dynloader.d



M:6YK86=E+D0 1#L-
M92!(34]$54Q%('-Y<TUO9'5L93L-" EP<F]T96-T960 =&AI<R  8VAA<EM=

M.PT*"0EI9B H("%S>7--;V1U;&4 *2!T:')O=R!N97< 17AC97!T:6]N*" B
M=6YA8FQE('1O(&QO860 <VAA<F5D(&QI8G)A<GD (B!^('!A=&  *3L-" E]

M9G5N8TYA;64 *0T*"7L-" D)1D%24%)/0R!F<" ]($=E=%!R;V-!9&1R97-S
M*"!S>7--;V1U;&4L(&-A<W0H8VAA<BHI9G5N8TYA;64 *3L-" D):68 *" A
M9G  *2!T:')O=R!N97< 17AC97!T:6]N*" B=6YA8FQE('1O(&=E="!F=6YC

M<')I=F%T92!S=&%T:6, 4VAA<F5D3&EB<F%R>5MC:&%R6UU=(&QO861E9#L-
M" EP=6)L:6, <W1A=&EC(%-H87)E9$QI8G)A<GD ;&]A9$QI8G)A<GDH(&-H

M*'-L(#T ;&]A9&5D6W!A=&A=*2 ]/3T ;G5L;" I(')E='5R;B!L;V%D961;
M<&%T:%T /2!N97< 4VAA<F5D3&EB<F%R>2  <&%T:" I.PT*"0ER971U<FX 

M*"!C:&%R6UT ;&EB+"!C:&%R6UT ;F%M92 I('L-" D)<F5T=7)N(&-A<W0H
M5"DH*%-H87)E9$QI8G)A<GDN;&]A9$QI8G)A<GDH(&QI8B I*2YG971&=6YC




M(&YE=R!%>&-E<'1I;VXH(")3:&%R960 1G5N8W1I;VX ;F]T(&QO861E9"( 



M;&%T92!$>6Y0<F]C*"!,:6YK86=E(%0 .B!,:6YK86=E+E=I;F1O=W, *2![

M(&YE=R!%>&-E<'1I;VXH(")3:&%R960 1G5N8W1I;VX ;F]T(&QO861E9"( 
M*3L ?2 -" D)='EP961E9B!V;VED(" J9G I*"D /2 F97)F.PT*"7T-" EI
M;G-T86YC92!$>6XH(&9P("D 9'EN1G5N8SL-" EA;&EA<R!D>6Y&=6YC+G5S

M"G1E;7!L871E($1Y;E!R;V,H($QI;FMA9V4 5" Z($QI;FMA9V4N0R I('L-


M"71Y<&5D968 =F]I9" H*F9P*2 I(#T



M9"!E<F8H(%  <" I('L =&AR;W< ;F5W($5X8V5P=&EO;B  (E-H87)E9"!&
M=6YC=&EO;B!N;W0 ;&]A9&5D(B I.R!]( T*"71Y<&5D968 =F]I9" H*F9P
M*2  4" I(#T )F5R9CL-" EI;G-T86YC92!$>6XH(&9P("D 9'EN1G5N8SL-




M:&%R960 1G5N8W1I;VX ;F]T(&QO861E9"( *3L ?2 -" D)='EP961E9B!V
M;VED(" J9G I*"!0("D /2 F97)F.PT*"7T-" EI;G-T86YC92!$>6XH(&9P



M('L-" D)=F]I9"!E<F8H(%  <" I('L =&AR;W< ;F5W($5X8V5P=&EO;B  
M(E-H87)E9"!&=6YC=&EO;B!N;W0 ;&]A9&5D(B I.R!]( T*"0ET>7!E9&5F

M9G  *2!D>6Y&=6YC.PT*"6%L:6%S(&1Y;D9U;F,N=7-E('5S93L-" EA;&EA
M<R!D>6Y&=6YC+G)E<75I<F4 <F5Q=6ER93L-"GT-" T*=&5M<&QA=&4 1'EN
M4')O8R  3&EN:V%G92!4(#H
M9"!E<F8H(% P(' P+"!0,2!P,2 I('L =&AR;W< ;F5W($5X8V5P=&EO;B  
M(E-H87)E9"!&=6YC=&EO;B!N;W0 ;&]A9&5D(B I.R!R971U<FX 4BYI;FET


M8RYU<V4 =7-E.PT*"6%L:6%S(&1Y;D9U;F,N<F5Q=6ER92!R97%U:7)E.PT*

M;F1O=W,L(% P+"!0,2 I('L-" EE>'1E<FX *%=I;F1O=W,I('L-" D)=F]I
M9"!E<F8H(% P(' P+"!0,2!P,2 I('L =&AR;W< ;F5W($5X8V5P=&EO;B  
M(E-H87)E9"!&=6YC=&EO;B!N;W0 ;&]A9&5D(B I.R!R971U<FX 4BYI;FET
M.R!]( T*"0ET>7!E9&5F('9O:60 *"IF<"DH(% P+"!0,2 I(#T )F5R9CL-

M1G5N8RYU<V4 =7-E.PT*"6%L:6%S(&1Y;D9U;F,N<F5Q=6ER92!R97%U:7)E





M;G-T86YC92!$>6XH(&9P("D 9'EN1G5N8SL-" EA;&EA<R!D>6Y&=6YC+G5S

M" T*=&5M<&QA=&4 1'EN1G5N8R  3&EN:V%G92!4("D >PT*"6EN<W1A;F-E


M:6%S(')E86Q496UP;&%T92YU<V4 =7-E.PT*"6%L:6%S(')E86Q496UP;&%T


M(')E86Q496UP;&%T93L-" EA;&EA<R!R96%L5&5M<&QA=&4N97)F(&5R9CL-


M=6ER93L-"GT-" T*=&5M<&QA=&4 1'EN1G5N8R  3&EN:V%G92!4(#H 3&EN
M:V%G92Y$+"!2("D >PT*"5( 97)F*"D >R!T:')O=R!N97< 17AC97!T:6]N
M*" B4VAA<F5D($9U;F-T:6]N(&YO="!L;V%D960B("D[(')E='5R;B!2+FEN

M($1Y;B  9G  *2!D>6Y&=6YC.PT*"6%L:6%S(&1Y;D9U;F,N=7-E('5S93L-
M" EA;&EA<R!D>6Y&=6YC+G)E<75I<F4 <F5Q=6ER93L-"GT-" T*=&5M<&QA
M=&4 1'EN1G5N8R  3&EN:V%G92!4(#H

M*" B4VAA<F5D($9U;F-T:6]N(&YO="!L;V%D960B("D[(')E='5R;B!2+FEN



M96UP;&%T92!$>6Y&=6YC*"!,:6YK86=E(%0 .B!,:6YK86=E+E=I;F1O=W,L

M<F]W(&YE=R!%>&-E<'1I;VXH(")3:&%R960 1G5N8W1I;VX ;F]T(&QO861E
M9"( *3L <F5T=7)N(%(N:6YI=#L ?2 -" D)='EP961E9B!2(" J9G I*"D 
M/2 F97)F.PT*"7T-" EI;G-T86YC92!$>6XH(&9P("D 9'EN1G5N8SL-" EA



M8R  5"P 4" I(')E86Q496UP;&%T93L-" EA;&EA<R!R96%L5&5M<&QA=&4N


M<75I<F4 <F5Q=6ER93L-"GT-" T*=&5M<&QA=&4 1'EN1G5N8R  3&EN:V%G
M92!4(#H
M>6Y0<F]C*"!4+"!0("D <F5A;%1E;7!L871E.PT*"6%L:6%S(')E86Q496UP
M;&%T92YE<F8 97)F.PT*"6%L:6%S(')E86Q496UP;&%T92YF<"!F<#L-" EA
M;&EA<R!R96%L5&5M<&QA=&4N=7-E('5S93L-" EA;&EA<R!R96%L5&5M<&QA

M:6YK86=E(%0 .B!,:6YK86=E+E=I;F1O=W,L(%( .B!V;VED+"!0("D >PT*


M+F9P(&9P.PT*"6%L:6%S(')E86Q496UP;&%T92YU<V4 =7-E.PT*"6%L:6%S

M($1Y;D9U;F,H($QI;FMA9V4 5" Z($QI;FMA9V4N1"P 4BP 4" I('L-" E2
M(&5R9B  4"!P("D >R!T:')O=R!N97< 17AC97!T:6]N*" B4VAA<F5D($9U

M961E9B!2(" J9G I*% I(#T )F5R9CL-" EI;G-T86YC92!$>6XH(&9P("D 



M("  5VEN9&]W<R I('L-" D)4B!E<F8H(%  <" I('L =&AR;W< ;F5W($5X
M8V5P=&EO;B  (E-H87)E9"!&=6YC=&EO;B!N;W0 ;&]A9&5D(B I.R!R971U
M<FX 4BYI;FET.R!]( T*"0ET>7!E9&5F(%( *"IF<"DH4"D /2 F97)F.PT*
M"7T-" EI;G-T86YC92!$>6XH(&9P("D 9'EN1G5N8SL-" EA;&EA<R!D>6Y&



M:')O=R!N97< 17AC97!T:6]N*" B4VAA<F5D($9U;F-T:6]N(&YO="!L;V%D


M"6%L:6%S(&1Y;D9U;F,N=7-E('5S93L-" EA;&EA<R!D>6Y&=6YC+G)E<75I
M<F4 <F5Q=6ER93L-"GT-"G1E;7!L871E($1Y;D9U;F,H($QI;FMA9V4 5" Z
M($QI;FMA9V4N1"P 4B Z('9O:60L(% P+"!0,2 I('L-" EI;G-T86YC92!$


M.PT*"6%L:6%S(')E86Q496UP;&%T92YU<V4 =7-E.PT*"6%L:6%S(')E86Q4

M*"!,:6YK86=E(%0 .B!,:6YK86=E+E=I;F1O=W,L(%( .B!V;VED+"!0,"P 

M;7!L871E.PT*"6%L:6%S(')E86Q496UP;&%T92YE<F8 97)F.PT*"6%L:6%S
M(')E86Q496UP;&%T92YF<"!F<#L-" EA;&EA<R!R96%L5&5M<&QA=&4N=7-E
M('5S93L-" EA;&EA<R!R96%L5&5M<&QA=&4N<F5Q=6ER92!R97%U:7)E.PT*
M?0T*=&5M<&QA=&4 1'EN1G5N8R  3&EN:V%G92!4(#H
M(#H
M+"!0,2 I(')E86Q496UP;&%T93L-" EA;&EA<R!R96%L5&5M<&QA=&4N97)F


M<F4 <F5Q=6ER93L-"GT-" T*=&5M<&QA=&4 1'EN1G5N8R  3&EN:V%G92!4
M(#H
M,2!P,2 I('L =&AR;W< ;F5W($5X8V5P=&EO;B  (E-H87)E9"!&=6YC=&EO
M;B!N;W0 ;&]A9&5D(B I.R!R971U<FX 4BYI;FET.R!]( T*"71Y<&5D968 



M:6YK86=E(%0 .B!,:6YK86=E+E=I;F1O=W,L(%(L(% P+"!0,2 I('L-" EE

M('1H<F]W(&YE=R!%>&-E<'1I;VXH(")3:&%R960 1G5N8W1I;VX ;F]T(&QO
M861E9"( *3L <F5T=7)N(%(N:6YI=#L ?2 -" D)='EP961E9B!2(" J(&9P
M*2A0,"Q0,2D /2 F97)F.PT*"7T-" EI;G-T86YC92!$>6XH(&9P("D 9'EN




M97!T:6]N*" B4VAA<F5D($9U;F-T:6]N(&YO="!L;V%D960B("D[(')E='5R


M9'EN1G5N8RYU<V4 =7-E.PT*"6%L:6%S(&1Y;D9U;F,N<F5Q=6ER92!R97%U
M:7)E.PT*?0T*=&5M<&QA=&4 1'EN1G5N8R  3&EN:V%G92!4(#H 3&EN:V%G
M92Y$+"!2(#H

M86Q496UP;&%T92YE<F8 97)F.PT*"6%L:6%S(')E86Q496UP;&%T92YF<"!F
M<#L-" EA;&EA<R!R96%L5&5M<&QA=&4N=7-E('5S93L-" EA;&EA<R!R96%L
M5&5M<&QA=&4N<F5Q=6ER92!R97%U:7)E.PT*?0T*=&5M<&QA=&4 1'EN1G5N
M8R  3&EN:V%G92!4(#H 3&EN:V%G92Y7:6YD;W=S+"!2(#H

M("D <F5A;%1E;7!L871E.PT*"6%L:6%S(')E86Q496UP;&%T92YE<F8 97)F
M.PT*"6%L:6%S(')E86Q496UP;&%T92YF<"!F<#L-" EA;&EA<R!R96%L5&5M
M<&QA=&4N=7-E('5S93L-" EA;&EA<R!R96%L5&5M<&QA=&4N<F5Q=6ER92!R
M97%U:7)E.PT*?0T*=&5M<&QA=&4 1'EN1G5N8R  3&EN:V%G92!4(#H 3&EN


M(')E86Q496UP;&%T92YE<F8 97)F.PT*"6%L:6%S(')E86Q496UP;&%T92YF
M<"!F<#L-" EA;&EA<R!R96%L5&5M<&QA=&4N=7-E('5S93L-" EA;&EA<R!R
M96%L5&5M<&QA=&4N<F5Q=6ER92!R97%U:7)E.PT*?0T*+RH-"G1E;7!L871E


M;&%T93L-" EA;&EA<R!R96%L5&5M<&QA=&4N97)F(&5R9CL-" EA;&EA<R!R





M;F]T(&QO861E9"( *3L <F5T=7)N(%(N:6YI=#L ?2 -" ET>7!E9&5F(%( 

M*2!D>6Y&=6YC.PT*"6%L:6%S(&1Y;D9U;F,N=7-E('5S93L-" EA;&EA<R!D
M>6Y&=6YC+G)E<75I<F4 <F5Q=6ER93L-"GT-"G1E;7!L871E($1Y;D9U;F,H


M(' Q+"!0,B!P,B I('L =&AR;W< ;F5W($5X8V5P=&EO;B  (E-H87)E9"!&
M=6YC=&EO;B!N;W0 ;&]A9&5D(B I.R!R971U<FX 4BYI;FET.R!]( T*"0ET

M86YC92!$>6XH(&9P("D 9'EN1G5N8SL-" EA;&EA<R!D>6Y&=6YC+G5S92!U

M;&%T92!$>6Y&=6YC*"!,:6YK86=E(%0 .B!,:6YK86=E+D,L(%(L(% P+"!0


M1G5N8W1I;VX ;F]T(&QO861E9"( *3L <F5T=7)N(%(N:6YI=#L ?2 -" D)



`
end

begin 666 winmm.d



M(%=I;F1O=W,L($U-4D5354Q4+"!U:6YT("D 25])7TQD<CL-"FEN<W1A;F-E
M($1Y;D9U;F,H(%=I;F1O=W,L($173U)$("D 25]67TQD<CL-" T*25])7TQD



M;6TN9&QL(BP (G1I;65"96=I;E!E<FEO9"( *3L-" E)7TE?3&1R+G5S92  
M=&EM945N9%!E<FEO9"P (" B=VEN;6TN9&QL(BP (G1I;65%;F1097)I;V0B

9;"(L(")T:6UE1V5T5&EM92( *3L-"GT-" ``
`
end
Feb 20 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
news:b33mmg$3fr$1 digitaldaemon.com...
 as D lacks the delphi extern 'foo.dll'
 I've written (and now with 0.56 it works). a dynamic loading module.
 the example on how to use loads the winmm.dll and allows you to use
 timeBeginPeriod, etc.

 hope someone else finds this useful.

 there are some problems with templates that I've got to checkout, and it
 would be good if there was a better way to write the templates.
Let's pin down why things are going wrong with the templates - the other reports posted about templates were bugs in my implementation, the concept was still sound.
Feb 21 2003
parent reply "Mike Wynn" <mike.wynn l8night.co.uk> writes:
 there are some problems with templates that I've got to checkout, and it
 would be good if there was a better way to write the templates.
Let's pin down why things are going wrong with the templates - the other reports posted about templates were bugs in my implementation, the concept was still sound.
I meant problems with the template mainly due to my programming, or way I'm trying to use them. I think all the bugs that I managed to encounter have been posted. I posted this as I find it useful, and am not that experianced with templates, I use them in C++ a little not done any hardcore c++ for a year or two, (even them I made little use of templating) most of the code I written on the past 2 years has been Java, C or Delphi. so I was curious if there was a better way to achieve the same results. some of the 'problems' I encountered which are highlighted in this code are; no way to create param list template types so there is fixed number of params that can be used in a dynamic func. however allowing a param list in a template would also require internal (rather than external) specilization, a switch on how many params or ever their type (like a case in record in pascal/delphi) which means in many cases the current methods for templating are fine as there are very few cases when a param list within a template would not be used as anything more than a param list (no trying to access actual values etc). void as a type requires a specialisation template foo(T) { T func() { return T.init; } } instance foo( void ) bar; // no allowed :( no return allowed from void func templates have their own linkage (which is good ... but not for this code) so again I had too cheat and create a Linkage enum and then specialise. somthing like template( char[] L, T ) { extern( L ) { T func() { return t.init; } } might be nice. these problems are not new, for instance the c++ http://sourceforge.net/projects/sigslot/ library also have a lot of reuse of the same code to solve similar problems (or should I say lack of syntax) this is not a critisism of D templates (I like templates, although see them as usefull for library code more than app code) just an observation on problem I ran into, and a question to see if someone can think up a better solution without resorting to requests for templates as params to templates or template that inherit from templates. (mmm templated templates that sounds like the classic "any problem can be solved by adding another level of indirection" :) Mike.
Feb 21 2003
parent reply "Walter" <walter digitalmars.com> writes:
"Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
news:b370l3$abu$1 digitaldaemon.com...
 no way to create param list template types so there is fixed number of
 params that can be used in a dynamic func.
 however allowing a param list in a template would also require internal
 (rather than external) specilization, a switch
 on how many params or ever their type (like a case in record in
 pascal/delphi) which means in many cases the current
 methods for templating are fine as there are very few cases when a param
 list within a template would not be used as
 anything more than a param list (no trying to access actual values etc).
I'm lost with that.
 void as a type requires a specialisation
 template foo(T) {
     T func() { return T.init; }
 }
 instance foo( void ) bar; // no allowed :( no return allowed from void
func That can be fixed.
 templates have their own linkage (which is good ... but not for this code)
 so again I had too cheat and create a Linkage enum and then specialise.
 somthing like
 template( char[] L, T ) {
     extern( L ) { T func() { return t.init; }
 }
 might be nice.
I never thought of that.
Feb 22 2003
parent "Mike Wynn" <mike.wynn l8night.co.uk> writes:
"Walter" <walter digitalmars.com> wrote in message
news:b38icr$1m93$1 digitaldaemon.com...
 "Mike Wynn" <mike.wynn l8night.co.uk> wrote in message
 news:b370l3$abu$1 digitaldaemon.com...
 no way to create param list template types so there is fixed number of
 params that can be used in a dynamic func.
 however allowing a param list in a template would also require internal
 (rather than external) specilization, a switch
 on how many params or ever their type (like a case in record in
 pascal/delphi) which means in many cases the current
 methods for templating are fine as there are very few cases when a param
 list within a template would not be used as
 anything more than a param list (no trying to access actual values etc).
I'm lost with that.
consider; template one( R ) { alias R (*fp)(); } template one( R, P ) { alias R (*fp)(P); } template one( R, P0, P1 ) { alias R (*fp)(P0, P1); } is bounded to allow more params a new template has to be delcared as I see it any scheme to allow varargs templates would only benifit a small class of templates (i.e. the dyn loader lib I wrote and maybe sig/slot style libs). template one( R, P[] ) { alias R (*fp)(P); } template one( R, P[] ) { alias R (*fp)(P); class foo { abstract R evoke( P ); } R func( foo f, P ) { return f.evoke( P ); } } however this might be useful for my dynamic loading template where none of the template params are used or above were the params are passed to something else directly (sigslot lib is similar). but a can forsee that you might require processing P[0] etc differently if their types differ template one( R, P[] ) { alias R (*fp)(P); class foo { abstract R evoke( P ); } select( P[0] ) { case : int = R func( foo f, P ) { return cast(R)(new Integer( f.evoke( P ) )); } case : void = R func( foo f, P[1..] ) { return f.evoke( P[1..] ); } case : default = R func( foo f, P ) { return f.evoke( P ); } } this is just the same as template one( R, P0 : int, P[] ) { alias R (*fp)(P0, P); class foo { abstract R evoke( P ); } R func( foo f, P ) { return f.evoke( P ); } } template one( R, P0 : void, P[] ) { alias R (*fp)(P0, P); class foo { abstract R evoke( P ); } R func( foo f, P ) { return f.evoke( P ); } } template one( R, P0, P[] ) { alias R (*fp)(P0, P); class foo { abstract R evoke( P ); } R func( foo f, P ) { return f.evoke( P ); } } it would be good not to have to cut'n'paste so much, (hence the sugestion of templates inheriting from templates although how that works in reality I've no idea and think it would all end in tears ) also template matching template one( R, B[], I : int, P[] ) one( float, long, long, int, float, float ) -> R:float, B[long, long], I:int, P[float, float] one( float, int, int, int, float ) !! whjat does this match why how and it is worth the effort ? so I conclude its a feature that solves one problem but creates a load more.
Feb 22 2003