Аннотация:
В этой статье мы с вами обсудим вопросы взаимодействия с компонентами .NET при помощи COM. Прочитав и осмыслив то, что здесь изложено, вы сможете с легкостью использовать компоненты .NET в ваших приложениях при помощи COM. А значит, сможете из любого вашего старого приложения, использующего WinApi, использовать практически все современные средства .NET.
Может кто занет почему у меня не проходит по этому условию. Вроде все правильно делаю.
//Создаём объект
//и сразу же получаем интересующий нас интерфейс ITestComponent
if (FAILED(CoCreateInstance(clsidOrbit,0,CLSCTX_ALL,__uuidof(ITestComponent),(void**)&pIOrbit)))
return;
Пути я прописывал, например, во так:
#import "C:\\3\\net\\My\\bin\\Release\\My.tlb" raw_interfaces_only Это нормально?
В командной строке я могу писать так: C:\5\sn.exe -k my.snk ?
Re[2]: Использование .NET компонентов при помощи COM
Здравствуйте, Rodion Online, Вы писали:
RO>Может кто занет почему у меня не проходит по этому условию. Вроде все правильно делаю.
RO> if (FAILED(CoCreateInstance(clsidOrbit,0,CLSCTX_ALL,__uuidof(ITestComponent),(void**)&pIOrbit))) RO> return;
у меня тоже так не работает — говорит, класс незарегистрирован
если положить Some.dll в тот каталог, где и клиент, то работает
PS пробовал делать и так gacutil /i Some.dll
всё равно не работает........
Правило наименьшего удивления: Программа должна работать так, чтобы это вызывало наименьшее удивление у пользователя.
Построй свой мини-горд на http://rumactep.myminicity.com/
Re[3]: Использование .NET компонентов при помощи COM
Здравствуйте, MACTEP, Вы писали:
MAC>если положить Some.dll в тот каталог, где и клиент, то работает MAC>PS пробовал делать и так gacutil /i Some.dll MAC>всё равно не работает........
PPS кстати, сборка видна в GacCash [\WINDOWS\assembly]
Правило наименьшего удивления: Программа должна работать так, чтобы это вызывало наименьшее удивление у пользователя.
Построй свой мини-горд на http://rumactep.myminicity.com/
Re[3]: Использование .NET компонентов при помощи COM
Здравствуйте, MACTEP, Вы писали:
MAC>если положить Some.dll в тот каталог, где и клиент, то работает MAC>PS пробовал делать и так gacutil /i Some.dll
А regasm Some.dll?
... << RSDN@Home 1.1.3 stable >>
Re[4]: Использование .NET компонентов при помощи COM
Здравствуйте, kuj, Вы писали:
kuj>А regasm Some.dll?
пробовал
но сейчас всё исправилось
использовалась какая-то старая версия Some.tlb
Правило наименьшего удивления: Программа должна работать так, чтобы это вызывало наименьшее удивление у пользователя.
Построй свой мини-горд на http://rumactep.myminicity.com/
Здравствуйте!
Кто-нибудь пробовал добавить в интерфейс свойство с типом string? У меня почему-то тогда не получается из клиента записать строку. То есть она вроде как записывается, но при попытке чтения значения свойства возвращается пустая строка
Re[2]: Использование .NET компонентов при помощи COM
Hello, "Hottabych1" > Кто-нибудь пробовал добавить в интерфейс свойство с типом string? У меня > почему-то тогда не получается из клиента записать строку. То есть она > вроде как записывается, но при попытке чтения значения свойства > возвращается пустая строка
Обычно работает. Надо смотреть финальный код
Posted via RSDN NNTP Server 2.0 beta
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Re[3]: Использование .NET компонентов при помощи COM
Здравствуйте, TK, Вы писали:
TK>Hello, "Hottabych1" >> Кто-нибудь пробовал добавить в интерфейс свойство с типом string? У меня >> почему-то тогда не получается из клиента записать строку. То есть она >> вроде как записывается, но при попытке чтения значения свойства >> возвращается пустая строка
TK>Обычно работает. Надо смотреть финальный код
Вот код сборки (файл Some.cs). Собственно, взят практически полностью из статьи. Только изменил свойство About.
using System;
using System.Reflection;
using System.Text;
//Данный атрибут определяет файл, в котором находится
//пара личных криптографических ключей,
//однозначно идентифицирующих сборку
//[assembly:AssemblyKeyFile("../Orbit.snk")]
//[assembly:AssemblyVersion("1.0.0.0")]namespace TestComponentLib
{
//Этот интерфейс нужен для взаимодействия
//с COM public interface ITestComponent
{
int Mul(int First, int Second);
int Square { get; set; }
String About { get; set; }
}
/// <summary>
/// Summary description for Class1.
/// </summary>public class TestComponent : ITestComponent
{
private int m_iSquare;
private string m_strAbout;
public TestComponent()
{
m_iSquare = 0;
}
// Implementing interface ITestComponentpublic int Mul(int First, int Second)
{
return First * Second;
}
public int Square
{
get
{
return m_iSquare;
}
set
{
m_iSquare = value * value;
}
}
public string About
{
get
{
return"This component is written in C#." + m_strAbout;
}
set
{
m_strAbout = value;
}
}
}
}
А вот код клиента на MFC:
// TestMFCNet.cpp : Defines the entry point for the console application.
//#include"stdafx.h"#include"TestMFCNet.h"#ifdef _DEBUG
#define new DEBUG_NEW
#endif
#import"e:\Мои документы\Visual Studio Projects\TestComponent\bin\Debug\TestComponent.tlb" raw_interfaces_only
using namespace TestComponent;
// The one and only application object
CWinApp theApp;
using namespace std;
void DoWork()
{
//Инициализируем СOM как STA, хотя значения это, в общем-то, не имеет,
//так как наш компонент автоматически поддерживает обе потоковые модели.if (FAILED(CoInitialize(NULL)))
return;
_bstr_t bstrCLSID;
CLSID clsidOrbit;
ITestComponent* pIOrbit;
HRESULT hr;
//Это ProgID нашего компонента.
//Как видите, он складывается из области видимости и имени
//самого компонента, записанных через точку.
bstrCLSID = "TestComponentLib.TestComponent";
//Получаем CLSID (Class ID) через ProgIDif (FAILED(CLSIDFromProgID (bstrCLSID, &clsidOrbit)))
return;
//Создаём объект
//и сразу же получаем интересующий нас интерфейс ITestComponentif (FAILED(CoCreateInstance(clsidOrbit, 0, CLSCTX_ALL, __uuidof(ITestComponent), (void**)&pIOrbit)))
return;
//BSTR strAbout;
LPWSTR strAbout;
//Запрашиваем информацию о компоненте
pIOrbit->put_About(L" HI!!!!!");
pIOrbit->get_About(&strAbout);
CW2CT str(strAbout);
//Для вывода используем UNICODE-версию MessageBoxlong res = 0;
pIOrbit->put_Square(232);
pIOrbit->get_Square(&res);
AfxMessageBox(str);
CoUninitialize();
}
int _tmain(int argc, TCHAR* argv[], TCHAR* envp[])
{
int nRetCode = 0;
// initialize MFC and print and error on failureif (!AfxWinInit(::GetModuleHandle(NULL), NULL, ::GetCommandLine(), 0))
{
// TODO: change error code to suit your needs
_tprintf(_T("Fatal Error: MFC initialization failed\n"));
nRetCode = 1;
}
else
{
DoWork();
}
return nRetCode;
}
Re[4]: Использование .NET компонентов при помощи COM
Здравствуйте, TK, Вы писали:
TK>Hello, "Hottabych1" >> >> Вот код сборки (файл Some.cs). Собственно, взят практически полностью из >> статьи. Только изменил свойство About.
TK>Не пробовал использовать нормальные BSTR? (для put_ особенно) TK>
TK>LPWSTR strAbout;
TK> //Запрашиваем информацию о компоненте
TK> pIOrbit->put_About(L" HI!!!!!");
TK> pIOrbit->get_About(&strAbout);
TK>
Вот это да! Сработало!!! Спасибо большое, уже мозги плавились ! А Вы не могли бы объяснить, почему так важно применять именно BSTR?
Re[6]: Использование .NET компонентов при помощи COM
Hello, "Hottabych1" > > Вот это да! Сработало!!! Спасибо большое, уже мозги плавились ! > А Вы не могли бы объяснить, почему так важно применять именно BSTR?
BSTR это не обычная строка, а скажем так, "паскалевская". это значит, что по
смещению [-1] хранится длина этой строки. Если маршалинг не используется, то
обычно это себя никак не проявляет. Однако, если возникает необходимость
маршалинга, то маршаллер считает мусор из [-1] смещения и получится то, что
получится...
Posted via RSDN NNTP Server 2.0 beta
Если у Вас нет паранойи, то это еще не значит, что они за Вами не следят.
Не пойму, почему не работает. Вот код, который я пытаюсь отладить.
Изменения по отношению к оригиналу состоят только в форматировании.
Кроме того я перенес файл Orbit.snk в папку C# проекта,
а C#dll перед запуском переношу в ту же папку, где находится C++ Some.exe.
C++ программа прекращает работу на строке, отмеченной **.
Что сие и как с ним бороться?
Спасибо!
using System;
using System.Reflection;
// Определение файла личных криптографических ключей, идентифицирующих сборку
[assembly:AssemblyKeyFile("Orbit.snk")]
[assembly:AssemblyVersion("1.0.0.0")]
namespace TestComponentLib
{ public interface ITestComponent // Этот интерфейс нужен для взаимодействия с COM
{ int Mul(int First, int Second);
int Square { get; set; }
String About { get; }
}
public class TestComponent: ITestComponent // Данный класс реализует интерфейс ITestComponent
{ public TestComponent() { m_iSquare = 0; }
public int Mul( int First, int Second) { return First * Second; }
private int m_iSquare;
public int Square { get { return m_iSquare; } set { m_iSquare = value * value; } }
public String About { get { return "This component wrote on C#"; } }
}
}