Read access to a .NET Assembly

Jun 29, 2009 at 7:18 PM

Hello,

I am just starting out trying to access a .NET assembly for some hardware.  I seem to be able to write to the DLL, but on a read I do not get the value I was expecting. 

The following code:

 

(clr-reference PICkitS)
(clr-using PICkitS)

(define (PICkitS-Initialize)
(clr-static-call Device Initialize_PICkitSerial))

(define PICkitS-Configure-USARTAsync
(case-lambda
[() (clr-static-call USART Configure_PICkitSerial_For_USARTAsync)]
[(p_aux1_def p_aux2_def p_aux1_dir p_aux2_dir p_rcv_dis p_voltage)
(clr-static-call USART
"Configure_PICkitSerial_For_USARTAsync(boolean, boolean, boolean, boolean, boolean, double)"
p_aux1_def p_aux2_def p_aux1_dir p_aux2_dir p_rcv_dis p_voltage)]
))

(define (PICkitS-Set_Baud_Rate p_baud)
(clr-static-call USART "Set_Baud_Rate(ushort)" p_baud))

(define (PICkitS-Get_Baud_Rate)
(clr-static-call USART Get_Baud_Rate))

(define (PICkitS-Cleanup)
(clr-static-call Device Cleanup))

(define (PICkitS-Run)
(display "PICkitS-Initialize : ") (display (PICkitS-Initialize)) (newline)
(display "PICkitS-Configure-USARTAsync : ") (display (PICkitS-Configure-USARTAsync)) (newline)
(display "PICkitS-Configure-USARTAsync( #f #f #t #t #t 5.0 ) : ") (display (PICkitS-Configure-USARTAsync #f #f #t #t #t 5.0)) (newline)
(display "PICkitS-Set_Baud_Rate(9600) : ") (display (PICkitS-Set_Baud_Rate 9600)) (newline)
(display "PICkitS-Get_Baud_Rate : ") (display (PICkitS-Get_Baud_Rate)) (newline)
; (display "(clr-type? PICkitS-Get_Baud_Rate) : ") (display (clr-type? (PICkitS-Get_Baud_Rate))) (newline)
)

(PICkitS-Run)
(display "PICkitS-Cleanup : ") (display (PICkitS-Cleanup)) (newline)

 

Yields the following result:

 

Shell stopped
(load "c:/Projects/SerialAnalyzer/VHE Protocol analyzer/pickits.ss")
> PICkitS-Initialize : #t
PICkitS-Configure-USARTAsync : #f
PICkitS-Configure-USARTAsync( #f #f #t #t #t 5.0 ) : #f
PICkitS-Set_Baud_Rate(9600) : #t
PICkitS-Get_Baud_Rate : #(clr-type UInt16)
PICkitS-Cleanup : #(unspecified)
>

The problem line is highlighted in bold above.  Why am I not getting a number?  How do I get the number?  Is there some form of help file for how to use the clr library that describes the function purpose and meaning of the parameters and return values?

Thanks for your help,

aschatte

 

Coordinator
Jun 29, 2009 at 7:39 PM

Hi

The clr- syntax does not do any conversion on return values, hence the little problem!

No problem though, there are a few ways to solve it.

1. Use the System.Convert class ie (clr-static-call System.Convert "ToInt32(UInt16)" some-unit16) . Note: I dont think ushort will work.

2. Use the (ironscheme conversions) library, and the follwoing proc: ->int32, ie (->int32 any-number).

3. You could try (clr-cast System.Int32 expr) where expr is your call (this does not always work).

Cheers

leppie

Jun 29, 2009 at 9:53 PM

Thank you for your very fast response!

I tried your suggestions and found that 1 & 2 worked and 3 did not as you indicated.  The code was modified to:

  (display "PICkitS-Set_Baud_Rate(9600) : ") (display (PICkitS-Set_Baud_Rate 9600)) (newline)
  (display "PICkitS-Get_Baud_Rate : ") (display (clr-static-call System.Convert "ToInt32(UInt16)" (PICkitS-Get_Baud_Rate))) (newline)
  (display "PICkitS-Get_Baud_Rate : ") (display (->int32 (PICkitS-Get_Baud_Rate))) (newline)
  (display "PICkitS-Get_Baud_Rate : ") (display (clr-cast System.Int32 (PICkitS-Get_Baud_Rate))) (newline)

and yielded:

PICkitS-Set_Baud_Rate(9600) : #t
PICkitS-Get_Baud_Rate : 9597
PICkitS-Get_Baud_Rate : 9597
PICkitS-Get_Baud_Rate : #(clr-type UInt16)

Thank you very much.  I saw the conversions library but thought it was for converting scheme objects to CLR values.  I tried using ->int16 thinking I was converting a Uint16 to a scheme number.  This gave me the same error.  This to let you know where I was coming from.  I looked at another Scheme to .NET package that seemed to work this way.  This one was not looking toward a strongly typed Scheme implementation.

I am sure that as I get more experience with this implementation some of the usage/parameter values will be more obvious.  Right now, they are not.  Although, I think I have what I need to get going.  Do you have any references that will help me understand how the various functions and their parameters should be used or set?  Or how the .NET interface works in general?

Thank you for your very good work and very fast response.

Best regards,

Al Schatte

Jul 1, 2009 at 7:20 PM

Hello,

After the above problem was fixed, I am now attempting to send and retrieve data from the hardware through its .NET DLL.  However, I do not seem to be able to locate the member functions.  Here is what I have, where the header is copied from the .NET DLL documentation:

#|
public static bool Retrieve_Data(uint p_byte_count, ref byte[] p_data_array)
///////////////////////////////////////////////////////////////////////////
//
// Returns: True if successful, False if not
//
// Inputs: p_byte_count - number of bytes to retrieve
// p_data_array - reference to an array of bytes - must be at
// least as large as p_byte_count
//
// Description: Retrieves p_byte_count bytes from the PICkitS.dll data buffer
// and copies them into p_data_array. After copying the data,
// the PICkitS.dll data buffer byte count is decremented by
// p_byte_count.
//
///////////////////////////////////////////////////////////////////////////
|#
(define (PICkitS-Retrieve_Data)
  (let* ((byte-count (PICkitS-Retrieve_Data_Byte_Count))
         (data (make-vector byte-count)))
    (if 
        (clr-static-call USART "Retrieve_Data(uint, uint32)" byte-count data)
        data
        #f)))

IronScheme gives the following results:

Shell stopped
(load "c:/Projects/SerialAnalyzer/VHE Protocol analyzer/pickits.ss")
> Unhandled exception during evaluation:
&who: clr-call
&message: member could not be resolved on type: USART
&syntax:
  form: ('USART 'Retrieve_Data(uint, uint32) '() g$byte-count$281$18p38L g$data$282$18p38L)
  subform: Retrieve_Data
&stacktrace
  [1]    at IronScheme.Runtime.Builtins.SyntaxError(Object who, Object message, Object form, Object subform)
  [2]    at IronScheme.Compiler.ClrCallInternalGenerator.Generate(Object args, CodeBlock cb)
  [3]    at IronScheme.Compiler.Generator.GetAst(Object args, CodeBlock cb, Boolean istailposition)
  [4]    at IronScheme.Compiler.IfGenerator.Generate(Object args, CodeBlock cb)
  [5]    at IronScheme.Compiler.Generator.GetAst(Object args, CodeBlock cb, Boolean istailposition)
  [6]    at IronScheme.Compiler.Generator.FillBody(CodeBlock cb, List`1 stmts, Cons body, Boolean allowtailcall)
  [7]    at IronScheme.Compiler.LambdaGenerator.Generate(Object args, CodeBlock c)
  [8]    at IronScheme.Compiler.CaseLambdaGenerator.Generate(Object args, CodeBlock c)
  [9]    at IronScheme.Compiler.Generator.GetAst(Object args, CodeBlock cb, Boolean istailposition)
  [10]    at IronScheme.Compiler.Generator.GetAst(Object args, CodeBlock cb, Boolean istailposition)
  [11]    at IronScheme.Compiler.Generator.FillBody(CodeBlock cb, List`1 stmts, Cons body, Boolean allowtailcall)
  [12]    at IronScheme.Compiler.LambdaGenerator.Generate(Object args, CodeBlock c)
  [13]    at IronScheme.Compiler.CaseLambdaGenerator.Generate(Object args, CodeBlock c)
  [14]    at IronScheme.Compiler.Generator.GetAst(Object args, CodeBlock cb, Boolean istailposition)
  [15]    at IronScheme.Compiler.Generator.GetAst(Object args, CodeBlock cb, Boolean istailposition)
  [16]    at IronScheme.Compiler.Generator.FillBody(CodeBlock cb, List`1 stmts, Cons body, Boolean allowtailcall)
  [17]    at IronScheme.Compiler.LibraryLetrecStarGenerator.Generate(Object args, CodeBlock c)
  [18]    at IronScheme.Compiler.Generator.GetAst(Object args, CodeBlock cb, Boolean istailposition)
  [19]    at IronScheme.Compiler.Generator.FillBody(CodeBlock cb, List`1 stmts, Cons body, Boolean allowtailcall)
  [20]    at IronScheme.IronSchemeLanguageContext.Compile(CodeBlock cb, Cons expr)
  [21]    at IronScheme.IronSchemeLanguageContext.CompileExpr(Cons expr)
  [22]    at IronScheme.Runtime.Builtins.CompileCore(CodeContext cc, Object expr)
  [23]    at IronScheme.Runtime.Builtins.EvalCore(CodeContext cc, Object expr)
  [24]    at IronScheme.Runtime.Builtins.DynamicWind(Object infunc, Object bodyfunc, Object outfunc)
  [25]    at IronScheme.Runtime.Builtins.DynamicWind(Object infunc, Object bodyfunc, Object outfunc)
  [26] psyntax.main::load(Object filename)
  [27]    at Microsoft.Scripting.ScriptCode.Run(CodeContext codeContext, Boolean tryEvaluate)
  [28]    at Microsoft.Scripting.ScriptCode.Run(ScriptModule module)
  [29]    at IronScheme.Runtime.Builtins.<>c__DisplayClass7.b__5()
  [30]    at IronScheme.Runtime.Builtins.EvalCore(CodeContext cc, Object expr)
  [31]    at IronScheme.Runtime.R6RS.Exceptions.WithExceptionHandler(Object handler, Object thunk)
  [32]    at IronScheme.Runtime.Builtins.CallWithCurrentContinuation(Object fc1)
  [33]    at Microsoft.Scripting.ScriptCode.Run(CodeContext codeContext, Boolean tryEvaluate)
  [34]    at Microsoft.Scripting.ScriptCode.Run(ScriptModule module)
  [35]    at Microsoft.Scripting.Hosting.CompiledCode.Evaluate(IScriptModule module)
  [36]    at Microsoft.Scripting.Hosting.ScriptEngine.ExecuteInteractiveCode(String code, IScriptModule module)
  [37]    at Microsoft.Scripting.Hosting.ScriptEngine.ExecuteCommand(String code, IScriptModule module)
  [38]    at Microsoft.Scripting.Shell.CommandLine.RunOneInteraction()
  [39]    at Microsoft.Scripting.Shell.CommandLine.TryInteractiveAction()
  [40]    at Microsoft.Scripting.Shell.CommandLine.RunInteractiveLoop()
  [41]    at Microsoft.Scripting.Shell.CommandLine.RunInteractive()
  [42]    at Microsoft.Scripting.Shell.CommandLine.Run()
  [43]    at Microsoft.Scripting.Shell.CommandLine.Run(IScriptEngine engine, IConsole console, ConsoleOptions options)
  [44]    at Microsoft.Scripting.Hosting.ConsoleHost.RunCommandLine(OptionsParser optionsParser)
  [45]    at Microsoft.Scripting.Hosting.ConsoleHost.ExecuteInternal()
  [46]    at Microsoft.Scripting.Hosting.ConsoleHost.Execute()
  [47]    at Microsoft.Scripting.Hosting.ConsoleHost.Run(String[] args)
  [48]    at IronScheme.Runtime.Program.Main(String[] args)
> 

How do I get IronScheme to find the Retrieve_Data function?

Thanks for your help,

Al Schatte

Coordinator
Jul 2, 2009 at 6:16 PM

Hi Al

Sorry for taking so long to reply (kinda forgot ;p ).

Unfortunately, IronScheme does not support ref or out parameters. Due to difficulty involved with it, IronScheme will probably not support it in the future either, unless I can find a valid reason.

For now, you can simply write a wrapper method in C# and call that, or if you are in control of the library, expose the methods so they do not need ref or out parameters.

That's the best I can offer  :|

Cheers

leppie

Jul 3, 2009 at 9:48 PM

Hi leppie,

Thanks for your help.  I can see where it might be a pain to implement robustly.  I don't have access to the library itself, but could wrap it as you suggest.

Thank you also for the work you have done on IronScheme.  It brought me out of some daunting places with respect to working with .NET DLLs from within Scheme.

Al Schatte