| Правила | Регистрация | Пользователи | Поиск | Сообщения за день | Все разделы прочитаны |  Справка по форуму | Файлообменник |

Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > .NET > .NET, Как передать массив в метод COM объекта?

.NET, Как передать массив в метод COM объекта?

Ответ
Поиск в этой теме
Непрочитано 17.05.2011, 13:37 #1
.NET, Как передать массив в метод COM объекта?
RomanZonta
 
Регистрация: 25.01.2011
Сообщений: 14

Здравствуйте.

Пишу утилиту на VB.NET для Autocad для построения протяжки (EXTRUDE) по заданным параметрам. Использую позднее связывание (без подключения библиотек Autocad).
Пытаюсь использовать метод AddSolid, но этот метод требует в качестве сечения регион.
Пытаюсь создать регион:

Код:
[Выделить все]
     Public Sub drawIBeam(ByVal blockObjRef As Object, _
                         ByVal beamHeight As Single, _
                         ByVal beamCapWidth As Single, _
                         ByVal beamCapThickness As Single, _
                         ByVal beamWall As Single)
        Dim ACad As Object
        Dim ADoc As Object
        Dim MoSpace As Object
        ACad = GetObject(, "AutoCAD.Application")
        ADoc = ACad.ActiveDocument
        MoSpace = ADoc.ModelSpace

        Dim buf As Object
        Dim lines(0 To 3) As Object

        lines(0) = drawLineInObject(blockObjRef, -beamCapWidth / 2, 0, beamCapWidth, 0, "Base lines")
        lines(1) = drawLineInObject(blockObjRef, -beamCapWidth / 2, 0, 0, beamCapThickness, "Base lines")
        lines(2) = drawLineInObject(blockObjRef, beamCapWidth / 2, 0, 0, beamCapThickness, "Base linesh")
        lines(3) = drawLineInObject(blockObjRef, -beamCapWidth / 2, beamCapThickness, beamCapWidth, 0, "Base lines")

        buf = blockObjRef.AddRegion(lines)

    End Sub
При этом возникает ошибка "Invalid object array" при вызове строки.

Код:
[Выделить все]
        buf = blockObjRef.AddRegion(lines)
Функция drawLineInObject рисует линию в объекте и возвращает эту линию.

Может быть, кто-нибудь знает как решить данную проблему?
Заранее благодарен за помощь.

Последний раз редактировалось RomanZonta, 30.05.2011 в 08:20.
Просмотров: 6851
 
Непрочитано 17.05.2011, 14:00
#2
Сергей Дубина


 
Регистрация: 06.04.2009
Сообщений: 706


Цитата:
Сообщение от RomanZonta Посмотреть сообщение
Dim lines(0 To 3) As Object
может:
Dim lines(0 To 3) As Variant?
__________________
КазнитьØнельзяØпомиловать:eek:
Сергей Дубина вне форума  
 
Автор темы   Непрочитано 17.05.2011, 14:06
#3
RomanZonta


 
Регистрация: 25.01.2011
Сообщений: 14


Цитата:
Сообщение от Сергей Дубина Посмотреть сообщение
может:
Dim lines(0 To 3) As Variant?
При это варианте я не могу установить слой у линий. Возникает ошибка "Key not found" при вызове строчки

Код:
[Выделить все]
 buf.layer = layer
в теле функции drawLineInObject.

Ниже привожу код этой функции (мб. там проблема).

Код:
[Выделить все]
Public Function drawLineInObject(ByVal blockObjRef As Object, _
                         ByVal startX As Single, _
                         ByVal startY As Single, _
                         ByVal lenghtX As Single, _
                         ByVal lenghtY As Single, _
                         ByVal layer As String)

        Dim begpRef(0 To 2) As Double
        Dim endpRef(0 To 2) As Double
        Dim buf As Object

        begpRef(0) = startX
        begpRef(1) = startY
        endpRef(0) = begpRef(0) + lenghtX
        endpRef(1) = begpRef(1) + lenghtY

        buf = blockObjRef.AddLine(begpRef, endpRef)
        buf.layer = layer

        Return buf

    End Function
RomanZonta вне форума  
 
Непрочитано 17.05.2011, 15:21
#4
Сергей Дубина


 
Регистрация: 06.04.2009
Сообщений: 706


Цитата:
Сообщение от RomanZonta Посмотреть сообщение
lines(0) = drawLineInObject(blockObjRef, -beamCapWidth / 2, 0, beamCapWidth, 0, "Base lines")
lines(1) = drawLineInObject(blockObjRef, -beamCapWidth / 2, 0, 0, beamCapThickness, "Base lines")
lines(2) = drawLineInObject(blockObjRef, beamCapWidth / 2, 0, 0, beamCapThickness, "Base linesh")
lines(3) = drawLineInObject(blockObjRef, -beamCapWidth / 2, beamCapThickness, beamCapWidth, 0, "Base lines")

buf = blockObjRef.AddRegion(lines)
blockObjRef.AddRegion(lines(0),lines(1),lines(2),lines(3))

В lines(...) ты вставляешь строки ("Base linesh"), ИМХО там должны быть значения координат. Если ты хочешь извлечь координаты из блоков надо "приложить дополнительные усилия".
__________________
КазнитьØнельзяØпомиловать:eek:
Сергей Дубина вне форума  
 
Автор темы   Непрочитано 17.05.2011, 15:34
#5
RomanZonta


 
Регистрация: 25.01.2011
Сообщений: 14


Цитата:
Сообщение от Сергей Дубина Посмотреть сообщение
blockObjRef.AddRegion(lines(0),lines(1),lines(2),lines(3))

В lines(...) ты вставляешь строки ("Base linesh")
В lines хранятся линии (объекты) которые возвращает функция drawLineInObject (см. пост №3). В этом то и проблема, что мне нужно передать массив объектов в метод.

Строка "Base lines" это название слоя.

Цитата:
Сообщение от Сергей Дубина Посмотреть сообщение
ИМХО там должны быть значения координат.
В хелпе Autocad указано, что там должен быть массив объектов.

Array of Objects
The array of objects forming the closed coplanar face to be made into a region.


Цитата:
Сообщение от Сергей Дубина Посмотреть сообщение
Если ты хочешь извлечь координаты из блоков надо "приложить дополнительные усилия".
Что Вы имеете ввиду под "дополнительными усилиями"?

Последний раз редактировалось RomanZonta, 17.05.2011 в 15:36. Причина: Дополнение
RomanZonta вне форума  
 
Непрочитано 17.05.2011, 15:41
#6
Сергей Дубина


 
Регистрация: 06.04.2009
Сообщений: 706


Цитата:
Сообщение от RomanZonta Посмотреть сообщение
В хелпе Autocad указано, что там должен быть массив объектов.
Тогда я пас. В моем хэлпе другое написано.
__________________
КазнитьØнельзяØпомиловать:eek:
Сергей Дубина вне форума  
 
Непрочитано 17.05.2011, 18:36
#7
Олег (jr.)

специалист по околачиванию грушевых деревьев
 
Регистрация: 14.09.2004
Pietari, Venäjä
Сообщений: 813


Бросается в глаза
Что сразу должно завалить Автокад:
все измерения заданы как Single а должны быть типа Double
Олег (jr.) вне форума  
 
Непрочитано 17.05.2011, 19:39
#8
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,550


Цитата:
Сообщение от Олег (jr.) Посмотреть сообщение
Бросается в глаза
Не лучше ли писать .net-сборку вместо COM клиента?
gomer вне форума  
 
Автор темы   Непрочитано 17.05.2011, 21:19
#9
RomanZonta


 
Регистрация: 25.01.2011
Сообщений: 14


Цитата:
Сообщение от Олег (jr.) Посмотреть сообщение
Бросается в глаза
Что сразу должно завалить Автокад:
все измерения заданы как Single а должны быть типа Double
Вы не правы. Тип Single имеют только задаваемые переменные. Все построения примитивов осуществляются с переменными begpRef и endpRef которые объявлены как Double.

Цитата:
Сообщение от gomer Посмотреть сообщение
Не лучше ли писать .net-сборку вместо COM клиента?
Лучше, но в данном случае, по некоторым причинам мне необходимо использовать COM.
RomanZonta вне форума  
 
Непрочитано 17.05.2011, 21:43
#10
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 36,872


Я извиняюсь, а blockObjRef - это указатель на вхождение блока или указатель на описание блока?
__________________

---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Непрочитано 17.05.2011, 22:16
#11
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,550


Я извиняюсь, а зачем в #1 MoSpace, AСad и ADoc?
gomer вне форума  
 
Непрочитано 17.05.2011, 22:18
#12
Кулик Алексей aka kpblc
Moderator

LISP, C# (ACAD 200[9,12,13,14])
 
Регистрация: 25.08.2003
С.-Петербург
Сообщений: 36,872


Это требуется по ActiveX-модели.
__________________

---
Обращение ко мне - на "ты".
Все, что сказано - личное мнение.
Кулик Алексей aka kpblc вне форума  
 
Автор темы   Непрочитано 17.05.2011, 22:28
#13
RomanZonta


 
Регистрация: 25.01.2011
Сообщений: 14


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Я извиняюсь, а blockObjRef - это указатель на вхождение блока или указатель на описание блока?
К сожаления я не знаю точных определений и различий между вхождением блока и указателем на описание блока, но я думаю (как я понял из названий этих терминов), что это указатель на вхождение блока, т.е. я "передаю" блок в функцию drawIBeam чтобы в этом блоке уже нарисовать протяжку (EXTRUDE).

Вот код вызова функции drawIBeam.

Код:
[Выделить все]
        'формируем имя блока
        gridBeam3DBlockName = "GRID_BEAM_" + gridBeamLenght.ToString

        'создаем блок
        gridBeam3DBlock = ADoc.Blocks.Add(InsPoint, gridBeam3DBlockName)

        'вызов функции построения балки в блоке 
        tAcadSubs.drawIBeam(gridBeam3DBlock, 180, 91, 8, 5.3)
RomanZonta вне форума  
 
Непрочитано 17.05.2011, 22:44
#14
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,550


Цитата:
Сообщение от Кулик Алексей aka kpblc Посмотреть сообщение
Это требуется по ActiveX-модели.
Просто они не используются в процедуре... и вызывать их надо в другом месте... или это бубен?

Цитата:
Сообщение от RomanZonta Посмотреть сообщение
gridBeamLenght.ToString
может gridBeamLength.ToString
gomer вне форума  
 
Непрочитано 17.05.2011, 23:30
#15
Олег (jr.)

специалист по околачиванию грушевых деревьев
 
Регистрация: 14.09.2004
Pietari, Venäjä
Сообщений: 813


Цитата:
Сообщение от RomanZonta Посмотреть сообщение
Вы не правы. Тип Single имеют только задаваемые переменные. Все построения примитивов осуществляются с переменными begpRef и endpRef которые объявлены как Double.
Рекомендую посмотреть учебные материалы:
http://download.autodesk.com/media/a...cs_Russian.zip
Олег (jr.) вне форума  
 
Непрочитано 18.05.2011, 00:07
#16
Pastor

это только кличка
 
Регистрация: 22.10.2006
Москва
Сообщений: 252


Честно говоря, вообще не понимаю, как может скомпилироваться строка
Код:
[Выделить все]
 buf = blockObjRef.AddRegion(lines)
если переменная blockObjRef объявлена как Object. У типа Object нет метода AddRegion()! Или я туплю, или это не VB.NET.
__________________
...в шее моей жилы железные, и лоб мой - медный...
Pastor вне форума  
 
Непрочитано 18.05.2011, 01:59
#17
Олег (jr.)

специалист по околачиванию грушевых деревьев
 
Регистрация: 14.09.2004
Pietari, Venäjä
Сообщений: 813


Так должно работать, перепиши по ситуации
(Проверил в 2009-м)
Код:
[Выделить все]
Imports System
Imports System.Runtime.InteropServices
Imports Autodesk.AutoCAD.Interop
Imports Autodesk.AutoCAD.Interop.Common


Module Module1
    Sub Main()
      
        Dim acApp As AcadApplication
        Dim progId As String = "AutoCAD.Application.17.2" '<--change to your current version
        Dim acDoc As AcadDocument = Nothing

        Dim oBlock As AcadBlock = Nothing

        acApp = GetObject("", progId)
        Try
        

            acApp.Application.Visible = True
            acDoc = acApp.Documents.Open("c:\bla\bla.dwg") '<-- file name to open
            acDoc = acApp.ActiveDocument
            Dim fname As String = acDoc.FullName
            Console.WriteLine(fname)
            Dim isexist = False

            For Each oBlkDef As AcadBlock In acDoc.Blocks

                If oBlkDef.Name = "myblock" Then '<--change blockname here
                    isexist = True
                    Exit For
                End If
            Next

            If Not isexist Then
                MsgBox("Block does not exist. Exit program")
                Exit Sub
            End If
            oBlock = acDoc.Blocks.Item("myblock") '<--change blockname here

            drawIBeam(oBlock, 1, 2, 0.1, 0.12)
           
            acDoc.Save()

            'acApp.Quit()'<--uncomment this line to suit

        Catch ex As System.Exception
            MsgBox(ex.Message & vbLf & ex.StackTrace)
            acDoc.Close(False)
            acApp.Quit()
            Marshal.FinalReleaseComObject(acApp)
        Finally

            oBlock = Nothing
            acDoc = Nothing
            acApp = Nothing

        End Try

    End Sub
    Public Sub drawIBeam(ByVal blockObjRef As AcadBlock, _
                     ByVal beamHeight As Single, _
                     ByVal beamCapWidth As Single, _
                     ByVal beamCapThickness As Single, _
                     ByVal beamWall As Single)

        Dim lines(0 To 3) As AcadEntity

        lines(0) = drawLineInObject(blockObjRef, -beamCapWidth / 2, 0, beamCapWidth, 0, "0")
        lines(1) = drawLineInObject(blockObjRef, -beamCapWidth / 2, 0, 0, beamCapThickness, "0")
        lines(2) = drawLineInObject(blockObjRef, beamCapWidth / 2, 0, 0, beamCapThickness, "0")
        lines(3) = drawLineInObject(blockObjRef, -beamCapWidth / 2, beamCapThickness, beamCapWidth, 0, "0")

        blockObjRef.AddRegion(lines)

    End Sub

    Public Function drawLineInObject(ByVal blockObjRef As AcadBlock, _
                             ByVal startX As Single, _
                             ByVal startY As Single, _
                             ByVal lenghtX As Single, _
                             ByVal lenghtY As Single, _
                             ByVal layer As String) As AcadLine

        Dim begpRef(0 To 2) As Double
        Dim endpRef(0 To 2) As Double
        Dim buf As AcadLine

        begpRef(0) = startX
        begpRef(1) = startY
        endpRef(0) = begpRef(0) + lenghtX
        endpRef(1) = begpRef(1) + lenghtY

        buf = blockObjRef.AddLine(begpRef, endpRef)
        buf.Layer = layer
        Return buf

    End Function
End Module
Олег (jr.) вне форума  
 
Автор темы   Непрочитано 18.05.2011, 08:21
#18
RomanZonta


 
Регистрация: 25.01.2011
Сообщений: 14


Цитата:
Сообщение от gomer Посмотреть сообщение
может gridBeamLength.ToString
Согласен, спасибо. Опечатка в названии процедуры, но проблему это не решает.

Цитата:
Сообщение от gomer Посмотреть сообщение
Я извиняюсь, а зачем в #1 MoSpace, AСad и ADoc?
Это будет использовано позднее в процедуре для вставки блока в пространство модели (я не стал приводит полный текст процедуры т.к. основная проблема в другом).

Цитата:
Сообщение от Олег (jr.) Посмотреть сообщение
Рекомендую посмотреть учебные материалы:
http://download.autodesk.com/media/a...cs_Russian.zip
Спасибо. Я уже просматривал данные материалы.

Цитата:
Сообщение от Pastor Посмотреть сообщение
Честно говоря, вообще не понимаю, как может скомпилироваться строка если переменная blockObjRef объявлена как Object. У типа Object нет метода AddRegion()! Или я туплю, или это не VB.NET.
Используется позднее привязывание.

Цитата:
Сообщение от Олег (jr.) Посмотреть сообщение
Так должно работать, перепиши по ситуации
(Проверил в 2009-м)
Спасибо за код, но проблема в том, что я не могу подключить библиотеки объектов Autocad (см. пост #1).

Код:
[Выделить все]
 
Imports Autodesk.AutoCAD.Interop
Imports Autodesk.AutoCAD.Interop.Common
С подключением библиотек все работает.

Последний раз редактировалось RomanZonta, 18.05.2011 в 08:21. Причина: дополнение
RomanZonta вне форума  
 
Непрочитано 18.05.2011, 20:01
#19
Pastor

это только кличка
 
Регистрация: 22.10.2006
Москва
Сообщений: 252


Продолжаю настаивать на том, что если речь идет о VB.NET, то код функции, представленной в посте №1 не может быть скомпилирован из-за наличия строчки:
Код:
[Выделить все]
buf = blockObjRef.AddRegion(lines)
поскольку переменная blockObjRef объявлена, как Object, а у объекта класса Object не существует метода AddRegion(). И позднее связывание здесь не при чем. Позднее связывание осуществляется, как минимум, с использованием Type.GetTypeFromProgID(), Activator.CreateInstance() и экземплярного метода InvokeMember() класса Type.

p.s.
VB.NET -это совсем не Visual Basic. Ничего общего, кроме внешнего сходства при беглом взгляде. Поэтому, лучше бы его (VB.NET) вовсе не придумывали: только мозги пудрить людям (ИМХО).
__________________
...в шее моей жилы железные, и лоб мой - медный...

Последний раз редактировалось Pastor, 18.05.2011 в 22:41.
Pastor вне форума  
 
Непрочитано 18.05.2011, 21:19
#20
gomer

строю, ломаю
 
Регистрация: 03.04.2008
Украина
Сообщений: 5,550


Цитата:
Сообщение от Pastor Посмотреть сообщение
Продолжаю настаивать на том, что если речь идет о VB.NET
Pastor, вы ничего не смыслите в программировании... и я тоже, тем более...
Однако же код похож на vb6 или даже на vba...

Цитата:
Сообщение от RomanZonta Посмотреть сообщение
Это будет использовано позднее в процедуре для вставки блока в пространство модели (я не стал приводит полный текст процедуры т.к. основная проблема в другом).
Следует разделять вставку блока и его создание, в первом случае аргументы - пространство вставки, точка вставки, во втором случае аргументы... документ, в котором создаете блок, и параметры вашей балки...
Все же очень просто... главное не промахнуться...
А GetObject нужно вызывать в самом начале при инициализации программы... Иначе он может возвратить совсем не то что нужно...
gomer вне форума  
Ответ
Вернуться   Форум DWG.RU > Программное обеспечение > Программирование > .NET > .NET, Как передать массив в метод COM объекта?

Размещение рекламы
Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Порекомендуйте литературу для повышения квалификации(грунты, геотехника) acid Поиск литературы, чертежей, моделей и прочих материалов 6 13.05.2015 22:14
Где написано, что Подрядчик обязан передавать исполнительную документацию ? drill_man Разное 164 15.01.2013 15:30
Какие документы должен передать подрядчик при передаче объекта незавершенного строительства заказчику. Diokles Технология и организация строительства 1 13.10.2010 17:52
Недостатки базисно-индексного метода расчета смет (например МДС-81.35.2004) ? drill_man Прочее. Отраслевые разделы 31 22.07.2010 14:52