Calling an non-DLL external function 
Author Message
 Calling an non-DLL external function

Is there a possibility to call an external function when just the
pointer to the function is known?

Thanks,

Udo



Sun, 14 Dec 2003 22:04:31 GMT  
 Calling an non-DLL external function
Udo

Quote:

> Is there a possibility to call an external function when just the
> pointer to the function is known?

Indeed. Its easiest if you know the prototype of the method in advance, and
slightly harder if you want to construct the call completely dynamically.
See the attached for some examples.

Regards

Blair

------------
Object subclass: #FunctionPointerEg
 instanceVariableNames: ''
 classVariableNames: ''
 poolDictionaries: ''
 classInstanceVariableNames: ''!
FunctionPointerEg guid: (GUID fromString:
'{67561145-D803-4B5E-9B96-9175EFCB4F48}')!
FunctionPointerEg comment: 'Invoking a function at a known address -
function prototype statically known.

 FunctionPointerEg new example1

Same again, but copying the method in case we want to call the same function
at multiple addresses:

 FunctionPointerEg new example2

Same again but dynamically constructed external call method (built with the
compiler).

 FunctionPointerEg new example3

Other dynamic techniques would be to choose an existing ExternalMethod to
use as a template, then modify a copy of it to create the desired function
description, or building an ExternalMethod entirely from scratch. These are
left as an exercise for the reader.
'!
!FunctionPointerEg categoriesForClass: !Unclassified! !
!FunctionPointerEg methodsFor!

beep: anInteger dwDuration: dwDuration
 <stdcall: bool Beep dword dword>
 ^self invalidCall!

example1
 | method |
 method := (self class compiledMethodAt: #beep:dwDuration:).
 method descriptorLiteral dwordAtOffset: 0 put: (KernelLibrary default
getProcAddress: 'Beep').

 300 to: 600 by: 100 do: [:i | self beep: i dwDuration: 100]
!

example2
 | method |
 method := (self class compiledMethodAt: #beep:dwDuration:) deepCopy.
 method descriptorLiteral dwordAtOffset: 0 put: (KernelLibrary default
getProcAddress: 'Beep').

 600 to: 300 by: -100 do: [:i | self beep: i dwDuration: 100]
!

example3
 "The easiest way to build an ExternalMethod dynamically is to get the
compiler to do it"
 | methodSource method |

 "Somehow we've constructed this string based on information we have about
the
 number and types of the arguments, etc"
 methodSource := 'i: i j: j <stdcall: bool _ dword dword>'.

 method := Compiler compile: methodSource in: Object.
 "Set the function pointer"
 method descriptorLiteral dwordAtOffset: 0 put: (KernelLibrary default
getProcAddress: 'Beep').

 (300 to: 600 by: 100), (600 to: 300 by: -100) do: [:i | method value: self
withArguments: (Array with: i with: 100)]
!

initialize
 | call |
 call := (self class compiledMethodAt: #beep:dwDuration:).
 call descriptorLiteral dwordAtOffset: 0 put: (KernelLibrary default
getProcAddress: 'Beep').
! !
!FunctionPointerEg categoriesFor:
#beep:dwDuration:!*-primitives!*-unclassified!public! !
!FunctionPointerEg categoriesFor: #example1!examples!public! !
!FunctionPointerEg categoriesFor: #example2!examples!public! !
!FunctionPointerEg categoriesFor: #example3!examples!public! !
!FunctionPointerEg categoriesFor: #initialize!initializing!public! !

!FunctionPointerEg class methodsFor!

new
 ^super new initialize! !
!FunctionPointerEg class categoriesFor: #new!instance creation!public! !



Mon, 15 Dec 2003 21:39:31 GMT  
 Calling an non-DLL external function
Blair,

thank you very much. This explains a lot of the exteral calling mechanisms for
me.

Thanks,

Udo

Quote:

> Udo


> > Is there a possibility to call an external function when just the
> > pointer to the function is known?

> Indeed. Its easiest if you know the prototype of the method in advance, and
> slightly harder if you want to construct the call completely dynamically.
> See the attached for some examples.

> Regards

> Blair

> ------------
> Object subclass: #FunctionPointerEg
>  instanceVariableNames: ''
>  classVariableNames: ''
>  poolDictionaries: ''
>  classInstanceVariableNames: ''!
> FunctionPointerEg guid: (GUID fromString:
> '{67561145-D803-4B5E-9B96-9175EFCB4F48}')!
> FunctionPointerEg comment: 'Invoking a function at a known address -
> function prototype statically known.

>  FunctionPointerEg new example1

> Same again, but copying the method in case we want to call the same function
> at multiple addresses:

>  FunctionPointerEg new example2

> Same again but dynamically constructed external call method (built with the
> compiler).

>  FunctionPointerEg new example3

> Other dynamic techniques would be to choose an existing ExternalMethod to
> use as a template, then modify a copy of it to create the desired function
> description, or building an ExternalMethod entirely from scratch. These are
> left as an exercise for the reader.
> '!
> !FunctionPointerEg categoriesForClass: !Unclassified! !
> !FunctionPointerEg methodsFor!

> beep: anInteger dwDuration: dwDuration
>  <stdcall: bool Beep dword dword>
>  ^self invalidCall!

> example1
>  | method |
>  method := (self class compiledMethodAt: #beep:dwDuration:).
>  method descriptorLiteral dwordAtOffset: 0 put: (KernelLibrary default
> getProcAddress: 'Beep').

>  300 to: 600 by: 100 do: [:i | self beep: i dwDuration: 100]
> !

> example2
>  | method |
>  method := (self class compiledMethodAt: #beep:dwDuration:) deepCopy.
>  method descriptorLiteral dwordAtOffset: 0 put: (KernelLibrary default
> getProcAddress: 'Beep').

>  600 to: 300 by: -100 do: [:i | self beep: i dwDuration: 100]
> !

> example3
>  "The easiest way to build an ExternalMethod dynamically is to get the
> compiler to do it"
>  | methodSource method |

>  "Somehow we've constructed this string based on information we have about
> the
>  number and types of the arguments, etc"
>  methodSource := 'i: i j: j <stdcall: bool _ dword dword>'.

>  method := Compiler compile: methodSource in: Object.
>  "Set the function pointer"
>  method descriptorLiteral dwordAtOffset: 0 put: (KernelLibrary default
> getProcAddress: 'Beep').

>  (300 to: 600 by: 100), (600 to: 300 by: -100) do: [:i | method value: self
> withArguments: (Array with: i with: 100)]
> !

> initialize
>  | call |
>  call := (self class compiledMethodAt: #beep:dwDuration:).
>  call descriptorLiteral dwordAtOffset: 0 put: (KernelLibrary default
> getProcAddress: 'Beep').
> ! !
> !FunctionPointerEg categoriesFor:
> #beep:dwDuration:!*-primitives!*-unclassified!public! !
> !FunctionPointerEg categoriesFor: #example1!examples!public! !
> !FunctionPointerEg categoriesFor: #example2!examples!public! !
> !FunctionPointerEg categoriesFor: #example3!examples!public! !
> !FunctionPointerEg categoriesFor: #initialize!initializing!public! !

> !FunctionPointerEg class methodsFor!

> new
>  ^super new initialize! !
> !FunctionPointerEg class categoriesFor: #new!instance creation!public! !



Tue, 16 Dec 2003 01:11:01 GMT  
 
 [ 3 post ] 

 Relevant Pages 

1. function calls to external dll in 'routine's

2. ACCEPT LOOP / EXTERNAL DLL / FUNCTION CALL / GPF

3. Calling External DLL Functions

4. Calling functions from a non-Clarion DLL, what embed for the prototypes

5. External NON CW DLL - Help

6. Using external DLL functions in a method

7. external rexx function dll with cygwin gcc ?

8. Rexx external function DLLs

9. OS/2, external functions in RxFtp.dll???

10. Creating external function with C DLL

11. VA 3.0 External C function and Crystal Report CRPE32.DLL

12. External calls without DLL/C

 

 
Powered by phpBB® Forum Software