.NET
cancel
Showing results for 
Show  only  | Search instead for 
Did you mean: 

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

9 REPLIES 9
Reply
Message 1 of 10
jshimkus
1455 Views, 9 Replies

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

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?

9 REPLIES 9
Message 2 of 10

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

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 3 of 10

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

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

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 4 of 10
jshimkus
in reply to: jshimkus

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?

 

 

Message 5 of 10


@jshimkus 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.

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 6 of 10
jshimkus
in reply to: jshimkus

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?

 

Message 7 of 10

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.

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 8 of 10
jshimkus
in reply to: jshimkus

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?

 

Message 9 of 10


CommCorp wrote:

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

 


Yes.

Відповідь корисна? Клікніть на "ВПОДОБАЙКУ" цім повідомленням! | Do you find the posts helpful? "LIKE" these posts!
Находите сообщения полезными? Поставьте "НРАВИТСЯ" этим сообщениям!
На ваше запитання відповіли? Натисніть кнопку "ПРИЙНЯТИ РІШЕННЯ" | Have your question been answered successfully? Click "ACCEPT SOLUTION" button.
На ваш вопрос успешно ответили? Нажмите кнопку "УТВЕРДИТЬ РЕШЕНИЕ"


Alexander Rivilis / Александр Ривилис / Олександр Рівіліс
Programmer & Teacher & Helper / Программист - Учитель - Помощник / Програміст - вчитель - помічник
Facebook | Twitter | LinkedIn
Expert Elite Member

Message 10 of 10
jshimkus
in reply to: jshimkus

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

 

 

Can't find what you're looking for? Ask the community or share your knowledge.

Post to forums  

Autodesk DevCon in Munich May 28-29th


Autodesk Design & Make Report

”Boost