Версия для печати темы
Нажмите сюда для просмотра этой темы в оригинальном формате
Форум программистов > Общие вопросы по .NET и C# > Подключить к C# COM объект


Автор: lumenxp 9.4.2010, 06:51
Здравствуйте.
Возможно вопрос и не сложный, но я не так давно знаком с С#.
Как правильно подключить COM объект к С#. Использую VS2008.

Вот пример из мануала
Код

Пример: C#
using S7PROSIMLib;
...
private S7ProSim ps;

Подскажите что означает строка "private S7ProSim ps;"

Далее для подключения функций в том же мануале производитель пишет 
Код

STDMETHOD(CS7ProSim::Connect)()

Но я так понял это код C++ и в C# он не совсем хорошо воспринимается.

Во вложении мануал.


Автор: lumenxp 9.4.2010, 08:10
Модификатор "private" запрещает доступ к полям и методам класса извне самого класса.
С эти стало яснее.

Как быть со строкой использования методов из COM объекта  S7PROSIMLib???

Автор: mrbrooks 9.4.2010, 08:30
C# и платформа .NET. Библиотека программиста Троелсен Э.
Глава 12. Взаимодействие с унаследованным программным кодом.

так же:http://msdn.microsoft.com/en-us/library/sd10k43k%28VS.71%29.aspx


Автор: lumenxp 9.4.2010, 12:42
Еще раз повторюсь что совсем недавно работаю с C#.
Ссылку на COM я добавил в самом начале.
Я не знаю как изменить код
Код

STDMETHOD(CS7ProSim::Connect)()

или
Код

S7ProSim1.Connect()

для того что бы С# это понял. 
Есть ли примеры?


Автор: lumenxp 10.4.2010, 10:44
Порыскал и нашел примеры.
Щас следующий косяк
Код

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using S7PROSIMLib;

namespace TestS7
{
    internal sealed class TestS7App

    {
        private S7ProSimClass ps = new S7ProSimClass();
        static void Main()
        {
            ps.Connect();
            ps.SetState("RUN_P");
            System.Console.ReadLine();
        }
    }
}


Вот что выдал компилятор.
ошибка CS0120: Для нестатического поля, метода или свойства "TestS7.TestS7App.ps" требуется ссылка на объект
(Связанное местоположение)

Help!!!

Автор: KelTron 10.4.2010, 12:17
Код

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using S7PROSIMLib;

namespace TestS7
{
    internal sealed class TestS7App
    {
        static void Main()
        {
            S7ProSimClass ps = new S7ProSimClass();
            ps.Connect();
            ps.SetState("RUN_P");
            System.Console.ReadLine();
        }
    }
}

Либо:
Код

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using S7PROSIMLib;

namespace TestS7
{
    internal sealed class TestS7App

    {
        private static S7ProSimClass ps = new S7ProSimClass();
        static void Main()
        {
            ps.Connect();
            ps.SetState("RUN_P");
            System.Console.ReadLine();
        }
    }
}

Автор: lumenxp 10.4.2010, 17:16
Спасибо!!!
Я дико извиняюсь но при усложнении кода возникли аналогичные ошибки

Код

namespace TestS7
{
    internal sealed class TestS7App
    {
        
       private object vData;
        static void Main()
        {
            
            S7ProSimClass ps = new S7ProSimClass();
            ps.Connect();
            ps.SetState("RUN_P");
            System.Console.ReadLine();
            int a = 0;
            int b = 0;
            bool m_bBoolIn = true;
            vData = m_bBoolIn;
            ps.WriteInputPoint(a, b, ref vData);
        }
    }
}

Теперь ругается на vData. 

Автор: KelTron 11.4.2010, 06:52
Функция Main статическая, это  значит что в ней можно обращаться только к статическим членам класса, т.е. тебе нужно либо vData сделать статической переменной, либо создавать экземпляр в функции Main. Также как и S7ProSimClass ps.

Автор: lumenxp 12.4.2010, 09:43
Еще раз спасибо KelTron.

Вобщем сделал как вы сказали

Код

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using S7PROSIMLib;

namespace S7Simulyator_dll
{
    public class Class1
    {
        private object vData;
        public static int Connect()
        {
            S7ProSimClass ps = new S7ProSimClass();
            Class1 vData = new Class1();
            ps.Connect();
            ps.SetState("RUN_P");
            bool m_bBoolIn = true;
            vData = m_bBoolIn;
            ps.WriteInputPoint(0, 1, ref vData);
            return 2;
         }
     }
}

Такие извращения с методом необходимы для того что бы приготовленную мной dll-ку мог скушать матлаб.
Подробнее я тут отписался http://forum.vingrad.ru/forum/topic-282027/anchor-entry2133591/15.html

Возникла новая проблема 
CS1503: Аргумент "3": преобразование типа из "ref bool" в "ref object" невозможно

Я делаю dll-ку на основании уже готового рабочего кода пиложения с экранной формой. 

Код

private void Click_WriteInputPoint(object sender, EventArgs e)
        {
                    int In = int.Parse(PointValueToWrite.Text);
                    if (In == 1)
                    {
                        m_bBoolIn = true;
                    }
                    else
                    {
                        m_bBoolIn = false;
                    }
                    m_nByteIndex = int.Parse(WPointByte.Text);
                    m_nBitIndex = int.Parse(WPointBit.Text);

                    vData = m_bBoolIn;
                    ps.WriteInputPoint(m_nByteIndex, m_nBitIndex, ref vData);

                    MessageBox.Show(MSG_OK, "S7ProSim-Example", MessageBoxButtons.OK, MessageBoxIcon.Information);
            }

Автор: KelTron 12.4.2010, 12:19
Цитата(lumenxp @  12.4.2010,  09:43 Найти цитируемый пост)
Вобщем сделал как вы сказали

Не совсем так...

Вообще я уже не понимаю где код, который ты используешь, везде разные куски какие то, приведи полный код, тогда уже можно будет что то сказать.

Автор: lumenxp 12.4.2010, 20:21
Извините за путаницу.

Код который сейчас использую

Код

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using S7PROSIMLib;

namespace S7Simulyator_dll
{
    public class Class1
    {
        private object vData;
        public static int Connect()
        {
            S7ProSimClass ps = new S7ProSimClass();
            Class1 vData = new Class1();
            ps.Connect();
            ps.SetState("RUN_P");
            bool m_bBoolIn = true;
            vData = m_bBoolIn;
            ps.WriteInputPoint(0, 1, ref vData);
            return 2;
         }
     }
}


Ошибка при данном коде 
CS1503: Аргумент "3": преобразование типа из "ref bool" в "ref object" невозможно

Такое извращение с методами 
Код

public static int Connect()
.......................
return 2;

необходимо для использования dll-ки в Matlab

Автор: KelTron 13.4.2010, 04:45
Мне непонятно что вот это такое, в чём тут смысл?:
Код

Class1 vData = new Class1();


Такое попробуй:
Код

namespace S7Simulyator_dll
{
    public class Class1
    {
        public static int Connect()
        {
            S7ProSimClass ps = new S7ProSimClass();
            ps.Connect();
            ps.SetState("RUN_P");
            object m_bBoolIn = true;
            ps.WriteInputPoint(0, 1, ref m_bBoolIn);
            return 2;
         }
     }
}

Автор: lumenxp 13.4.2010, 06:01
Дело в том что параметр функции ps.WriteInputPoint под названием vData должен быть object. В противном случае компилятор говорит что 

Наиболее подходящий перегруженный метод для "S7PROSIMLib.S7ProSimClass.WriteInputPoint(int, int, ref object)" имеет несколько недопустимых аргументов
Аргумент "3": преобразование типа из "ref bool" в "ref object" невозможно

Автор: KelTron 13.4.2010, 07:42
Смотри код внимательней...

Автор: lumenxp 14.4.2010, 18:01
Еще раз спасибо!
Простите за невнимательность, и за возможно глупые вопросы.
Указанная вам конструкция действительно заработала.
Я начал усложнять программу и вот что получилось

Код

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using S7PROSIMLib;

namespace S7Simulyator_dll
{
    public class Class1
    {
        public static int Connect()
        {
            S7ProSimClass ps = new S7ProSimClass();
            ps.Connect();
            ps.SetState("RUN_P");
            return 0;
        }

        public static int SetBitOut()
          {
            bool x = true;
            object vData = x;
            ps.WriteInputPoint(0, 4, ref vData);
            return 0;
         }
    }
}


Ошибка компилятора
Код

Элемент "ps" не существует в текущем контексте.    


Дилитанская попытка вставить S7ProSimClass ps = new S7ProSimClass(); привела к компиляции, но метод так и не отработал.

Автор: Alkash 14.4.2010, 19:54
Дык компилятор говорит - что он незнает что такое ps в SetBitOut(), соответственно определи его для всего класса

Автор: lumenxp 15.4.2010, 06:26
При объявлении для всего класса, а именно
Код

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using S7PROSIMLib;

namespace S7Simulyator_dll
{
    public class Class1
    {
        S7ProSimClass ps = new S7ProSimClass();
        public static int Connect()
        {
            
            ps.Connect();
            ps.SetState("RUN_P");
            return 0;
        }
......................

Получаем ошибку 
Код

Для нестатического поля, метода или свойства "S7Simulyator_dll.Class1.ps" требуется ссылка на объект

Автор: jonie 15.4.2010, 10:42
у вас функция Connect статическая, и в ней вы обращаетесь к нестатическому члену ps. Либо делайте его статическим, либо функцию Connect НЕ статической

Автор: lumenxp 15.4.2010, 10:55
Ни то ни другое я сделать не могу.
Сделать ps статическим членом нельзя т.к. не будет работать обращение к подключенному COM объекту.
Сделать функцию не статическо не могу т.к. с ней работает Матлаб. И еже она будет не статической он ничего не сможет сотворить.

Автор: jonie 15.4.2010, 11:42
Цитата


Сделать ps статическим членом нельзя т.к. не будет работать обращение к подключенному COM объекту.
врете вы всё.

ну хорошо, передавайте в Connect ссылку на Class1, и в функции уже раоботайте через неё.

Автор: lumenxp 15.4.2010, 11:45
Да ничего я не вру!
 smile 
Пожалуйста приведите пример ссылки на класс, который должен отработать в данной конструкции.

Автор: jonie 15.4.2010, 22:50
Код

    public class Class1
    {
        readonly S7ProSimClass ps = new S7ProSimClass();  //реадонли для неменяемых объектов - хорошая практика
        public static int Connect(Class1 selfref)
        {
            selfref.ps.Connect();
            selfref.ps.SetState("RUN_P");
            return 0;
        }
    }

//где-то в коде
Class1 cl = new Class1();
Class1.Connect(cl);

но вы врете насчет того что ссылка на COM не может быть статической.

Автор: lumenxp 16.4.2010, 06:28
Спасибо за ответ.

Вот что мне выдал Matlab при попытке использовать метод Connect

Код

??? No method 'Connect' with matching signature found for class
'S7Simulyator_dll.Class1'.

Попытки что то изменить в коде не привели к работоспособности.

Автор: jonie 16.4.2010, 07:38
lumenxp, а фиг его знает , как вы там указали сигнатуру..

Автор: lumenxp 16.4.2010, 17:36
Код

NET.addAssembly('D:\S7Simulyator_dll.dll');
db1 = S7Simulyator_dll.Class1.Connect();

Автор: jonie 16.4.2010, 20:51
lumenxp, ну правильно, теперь у вас коннект ждет экземпляра класса Class1, сделайте его в матлабе и передайте как параметр...

Автор: lumenxp 17.4.2010, 06:49
Пожалуйста более подробно опишите действия. Что значит сделать в Matlabe экземпляр класса?

Powered by Invision Power Board (http://www.invisionboard.com)
© Invision Power Services (http://www.invisionpower.com)