• Industries
  • Products
  • Buy
  • Services & Support
  • Communities
  • Discussion Groups

    .NET

    Reply
    Valued Contributor
    Posts: 84
    Registered: ‎03-19-2007

    Is Lisp "command" function not available when called from VB Dot Net?

    444 Views, 9 Replies
    05-10-2012 06:22 AM

    I'm trying to run a Lisp program by calling it from VB Dot Net.

    Just for testing, my Lisp code is as follows...

    (defun c:DoIt(textb)
    	(setq pntA (getpoint "\nPick A")
    		  pntB (getpoint pntA "\nPick B")
    		  )
    (setq curdoc (vla-get-activedocument (vlax-get-acad-object)))
    (setq mspace (vla-get-modelspace curdoc))
    (vla-addline mspace (vlax-3d-point pntA) (vlax-3d-point pntB))
    
    ; Vlisp works
    (vla-addText mspace (car textb) (vlax-3d-point (list 0 0 0)) 3.0)
    
    ; command line does not work, returns "invalid AutoCAD command:"
    (command "text" "c" (list 0 0 0) 3.0 0.0 textb)
    	)

     And my VB Dot Net code is...

    ublic Class MyPlugin
        <CommandMethod("runlisp", CommandFlags.Session)> _
        Public Sub runlisp()
            Dim commandargs As New ResultBuffer()
    
            commandargs.Add(New Autodesk.AutoCAD.DatabaseServices.TypedValue(LispDataType.Text, "c:doit"))
            commandargs.Add(New Autodesk.AutoCAD.DatabaseServices.TypedValue(LispDataType.Text, "ceil"))
    
            'commandargs.Add(New Autodesk.AutoCAD.DatabaseServices.TypedValue(LispDataType.ListBegin, -1))
            'commandargs.Add(New Autodesk.AutoCAD.DatabaseServices.TypedValue(LispDataType.Text, "ceil"))
            'commandargs.Add(New Autodesk.AutoCAD.DatabaseServices.TypedValue(LispDataType.ListEnd, -1))
    
            Dim m_ResultBuf As IntPtr = IntPtr.Zero
            Dim m_Return As Integer = acedInvoke(commandargs.UnmanagedObject, m_ResultBuf)
    
            commandargs.Dispose()
            If m_Return <> 5100 Then
                MsgBox(String.Format("Return value {0}", m_Return))
            End If
        End Sub
    
        <DllImport("acad.exe", CallingConvention:=CallingConvention.Cdecl, EntryPoint:="acedInvoke")> _
        Private Shared Function acedInvoke(ByVal args As IntPtr, ByRef result As IntPtr) As Integer
        End Function
    
    
    End Class

     As I've noted in the Lisp code, the Visual Lisp code to add text is working but the command line version does not, it returns "invalid AutoCAD command:".

    Am I doing something wrong or does "command" not work when the lisp is called from dot net?

    Please use plain text.
    Moderator
    Alexander.Rivilis
    Posts: 1,168
    Registered: ‎04-09-2008

    Re: Is Lisp "command" function not available when called from VB Dot N

    05-10-2012 07:29 AM in reply to: CommCorp

    To call LISP functions via acedInvoke, they must be registered using (vl-acad-defun)

    http://forums.autodesk.com/t5/NET/loading-a-lisp-with-dot-net-wizard/m-p/3083852#M24238


    Пожалуйста не забывайте про Утвердить в качестве решения!Утвердить в качестве решения и Give Kudos!Баллы
    Please remember to Accept Solution!Accept as Solution and Give Kudos!Kudos

    Please use plain text.
    Moderator
    Alexander.Rivilis
    Posts: 1,168
    Registered: ‎04-09-2008

    Re: Is Lisp "command" function not available when called from VB Dot N

    05-10-2012 01:49 PM in reply to: Alexander.Rivilis

    Oops! I see that you use command attribute CommandFlags.Session

    (command ...) as far as acedCommand() and acedCmd() can not been called from Application context.


    Пожалуйста не забывайте про Утвердить в качестве решения!Утвердить в качестве решения и Give Kudos!Баллы
    Please remember to Accept Solution!Accept as Solution and Give Kudos!Kudos

    Please use plain text.
    Valued Contributor
    Posts: 84
    Registered: ‎03-19-2007

    Re: Is Lisp "command" function not available when called from VB Dot N

    05-14-2012 03:41 AM in reply to: CommCorp

    Thank you for the replies.

    So is there NO way to use "command" in a Lisp function that is called from Dot Net?

    Or do I have something wrong?

     

     

    Please use plain text.
    Moderator
    Alexander.Rivilis
    Posts: 1,168
    Registered: ‎04-09-2008

    Re: Is Lisp "command" function not available when called from VB Dot N

    05-14-2012 03:54 AM in reply to: CommCorp

    CommCorp wrote:

    So is there NO way to use "command" in a Lisp function that is called from Dot Net?

    Or do I have something wrong?


    Change CommandFlags.Session with CommandFlags.Modal in your's VB.NET code and try again.


    Пожалуйста не забывайте про Утвердить в качестве решения!Утвердить в качестве решения и Give Kudos!Баллы
    Please remember to Accept Solution!Accept as Solution and Give Kudos!Kudos

    Please use plain text.
    Valued Contributor
    Posts: 84
    Registered: ‎03-19-2007

    Re: Is Lisp "command" function not available when called from VB Dot N

    05-14-2012 04:33 AM in reply to: CommCorp

    Thanks, that works for my simple example that I posted.

    But what I am really trying to do is this.

    I have a command method that opens and closes multiple drawings (has to be "Session" right?), when certain drawings are open I want to run a Lisp program in them, and that Lisp program contains "command" functions.

     

    So while the Session command method is running can I call a Modal command method?

     

    Please use plain text.
    Moderator
    Alexander.Rivilis
    Posts: 1,168
    Registered: ‎04-09-2008

    Re: Is Lisp "command" function not available when called from VB Dot N

    05-14-2012 04:48 AM in reply to: CommCorp

    IMHO. You can make two .NET command. One with Session flag, other with Modal flag.

    First command open/close dwg-file and start (with Document.SendStringToExecute method, or IAcadDocument.SendCommand method) second command, which call Lisp.


    Пожалуйста не забывайте про Утвердить в качестве решения!Утвердить в качестве решения и Give Kudos!Баллы
    Please remember to Accept Solution!Accept as Solution and Give Kudos!Kudos

    Please use plain text.
    Valued Contributor
    Posts: 84
    Registered: ‎03-19-2007

    Re: Is Lisp "command" function not available when called from VB Dot N

    05-14-2012 05:02 AM in reply to: CommCorp

    Thanks! You've been a big help, I will give that a try.

     

    One last question, can both of the command methods be in the same class?

     

    Please use plain text.
    Moderator
    Alexander.Rivilis
    Posts: 1,168
    Registered: ‎04-09-2008

    Re: Is Lisp "command" function not available when called from VB Dot N

    05-14-2012 05:04 AM in reply to: CommCorp

    CommCorp wrote:

    [...]One last question, can both of the command methods be in the same class?[...]

     


    Yes.


    Пожалуйста не забывайте про Утвердить в качестве решения!Утвердить в качестве решения и Give Kudos!Баллы
    Please remember to Accept Solution!Accept as Solution and Give Kudos!Kudos

    Please use plain text.
    Valued Contributor
    Posts: 84
    Registered: ‎03-19-2007

    Re: Is Lisp "command" function not available when called from VB Dot N

    05-15-2012 08:13 AM in reply to: CommCorp

    Sorry to bother you again but I have attempted to implement your suggestions but it still is not quite working for me.

    Close, but not quite. The program is opening the new drawing, and I can tell that it tries to execute the Lisp program because the command line says "Command: runlisp", but then it errors out with a "Fatal Error unhandled access violation". I cant' use "sendstringtoexecute" as you suggested because that does not run until the DotNet program has finished and at that point the drawings ive created are long closed.

    Attached is an abbreviated, but more acurate, code structure to show exactly what im trying to do.

    Do you see what I am doing wrong?

     

    Public Class DwgGenerator
    
      <CommandMethod("DwgGen", CommandFlags.Session)> _
        Public Sub Get_Data()
    	' figure which drawing to create and create it
    	
    		Create_constdwg(ConstFolder, DWGName, ConstLevel, progType, progFile, progCmnd, progExec)
    	End Sub
    	
    	Public Sub Create_constdwg(ByVal ConstFolder As String, ByVal DWGName As String, ByVal ConstLevel As String, _
                                   ByVal progType As String, ByVal progFile As String, ByVal progCmnd As String, ByVal progExec As String)
    	   ' create the new drawing, open and set as active dwg. Then run the Lisp program in it.
              Try
                Dim newdoc As Document = myAcadApp.DocumentManager.Add(TemplateDwgFullPath)
                Using newdoc.LockDocument
                    ' save it to its actual name
                    newdoc.Database.SaveAs(ConstFolder & DWGName & ".dwg", DwgVersion.Current)
                End Using
                newdoc.CloseAndDiscard()
    
                'open the newly created construct and set as the active document
                newdoc = myAcadApp.DocumentManager.Open(ConstFolder & DWGName & ".dwg", False, "")
                Using newdoc.LockDocument
                    myAcadApp.DocumentManager.MdiActiveDocument = newdoc
                    ' launch the Lisp program.
                    app.ActiveDocument.SendCommand("runlisp" & vbCr)
                 End Using
                newdoc.CloseAndSave(ConstFolder & DWGName & ".dwg")
    
            Catch ex As System.Exception
                MessageBox.Show(ex.Message, "Construct create Error")
            End Try
    							   
    	End Sub
    	
    	<CommandMethod("runlisp", CommandFlags.Modal)> _
        Public Sub runlisp()
            Dim commandargs As New ResultBuffer()
            app.ActiveDocument.SendCommand("(load """ & progFile & """)" & vbCr)
            commandargs.Add(New Autodesk.AutoCAD.DatabaseServices.TypedValue(LispDataType.Text, "c:netdrawshell"))
            commandargs.Add(New Autodesk.AutoCAD.DatabaseServices.TypedValue(LispDataType.Text, "ceil"))
    
            Dim m_ResultBuf As IntPtr = IntPtr.Zero
            Dim m_Return As Integer = acedInvoke(commandargs.UnmanagedObject, m_ResultBuf)
    
            commandargs.Dispose()
            If m_Return <> 5100 Then
                MsgBox(String.Format("Return value {0}", m_Return))
            End If
        End Sub
    	
    	<DllImport("acad.exe", CallingConvention:=CallingConvention.Cdecl, EntryPoint:="acedInvoke")> _
        Private Shared Function acedInvoke(ByVal args As IntPtr, ByRef result As IntPtr) As Integer
        End Function
    	
    End Class

     

     

    Please use plain text.