#c# #c #com #interop
#c# #c #com #взаимодействие
Вопрос:
Я пытаюсь создать очень простую COM dll для включения в проект C #, чтобы затем использовать для переноса некоторой функциональности C в COM-модуль для включения в проект C # (язык, используемый остальной частью базы кода).
Я включил COM dll, добавил класс в COM dll и создал его экземпляр в коде C #, но пока мне не удалось добавить новую функциональность в новый класс.
Вот что я сделал:
- Новое приложение Visual C # Windows Forms
- Щелкните правой кнопкой мыши решение-> Добавить-> Новый проект…
- Добавьте новый проект Visual C ATL (называемый MyCOMDLL)
- Параметры по умолчанию, выбранные в мастере проекта ATL (я также пробовал ставить галочку «Поддержка COM 1.0»)
- Щелкните правой кнопкой мыши MyCOMDLL project-> Добавить-> Класс
- Добавьте новый компонент Visual C ATL COM 1.0
- Введите ‘MyCOMObject’ в Short name, которое автоматически заполнило другие поля на вкладке ‘Имена’
- Остальные настройки оставил по умолчанию
- Создал проект MyCOMDLL
- Добавьте ссылку на новый MyCOMDLL.dll в приложение C # Windows Forms
- Щелкните правой кнопкой мыши проект приложения C # Windows Forms -> Свойства
- На вкладке «Сборка» установите целевую платформу на x86
- Добавьте «с использованием MYCOMDLLIB;» в файл Form1.cs
- Добавьте кнопку в форму и в кнопке щелкните добавить функцию
MyCOMDLLLib.MyCOMObjectClass myVariable = new MyCOMObjectClass();
Я пробовал разные вещи, поэтому не буду перечислять их, кроме самых очевидных здесь — я попытался добавить метод класса в MyCOMObject.h:
// CMyCOMObject
class ATL_NO_VTABLE CMyCOMObject :
public CComObjectRootEx,
public CComCoClass,
public IDispatchImpl
{
public:
CMyCOMObject()
{
}
DECLARE_PROTECT_FINAL_CONSTRUCT()
HRESULT FinalConstruct()
{
return S_OK;
}
void FinalRelease()
{
}
DECLARE_REGISTRY_RESOURCEID(IDR_MYCOMOBJECT)
DECLARE_NOT_AGGREGATABLE(CMyCOMObject)
BEGIN_COM_MAP(CMyCOMObject)
COM_INTERFACE_ENTRY(IMyCOMObject)
COM_INTERFACE_ENTRY(IDispatch)
END_COM_MAP()
// IMyCOMObject
public:
// SB: My attempt at adding a new method
int ReturnTwo()
{
return 2;
}
};
Метод ReturnTwo был виден в представлении класса CMyCOMObject, но не был виден в представлении класса MyCOMObjectClass в проекте приложения C # Windows Forms.
Любая помощь приветствуется.
Ответ №1:
Я попытался добавить метод класса в MyCOMObject.h
Этого недостаточно. Самым важным файлом в вашем проекте является файл .idl (язык описания интерфейса). Этот файл генерирует библиотеку типов, которая внедряется в DLL. Библиотека типов — это что .NET используется для создания библиотеки управляемого импорта. Добавленной вами функции там не будет, потому что вы не изменяли файл .idl.
Изменение интерфейсов является болезненным, если вы делаете это вручную, есть три места, которые необходимо отредактировать. Файлы .idl, .h и .cpp. Это лучше всего сделать с помощью мастера. В окне просмотра класса щелкните правой кнопкой мыши интерфейс (например, IFoo), Добавьте, Добавьте метод (или свойство). Затем переключитесь на файл .cpp, чтобы написать реализацию метода.
Комментарии:
1. Работает отлично, спасибо! Успешно использовал мастер для добавления методов и свойств, которые были видны в приложении C #, хотя, к вашему сведению, для всех остальных вам нужно будет избавиться от ранее сгенерированной библиотеки взаимодействия DLL при добавлении методов / свойств.
Ответ №2:
Вы снова скопировали свою новую сборку dll в проект C #?
Комментарии:
1. Попытался удалить ссылку из проекта C #, удалив сгенерированное взаимодействие. MyCOMDLLLib.dll и повторное добавление ссылки. Также пытался добавить функцию и переменную в . dll перед сборкой и добавлением в проект C # в первую очередь. Никакой радости ни в том, ни в другом случае.
2. Рисунок. Просто стоит попробовать. Возможно, у вас возникли проблемы с регистрацией COM. Обычно вам нужно зарегистрировать библиотеки DLL для COM, я думаю, C # делает это автоматически, только если вы также создаете DLL на C #.
3. Спасибо за предложения, Соггер. К сожалению, я почти уверен, что это не проблема с регистрацией. Ранее у меня были некоторые проблемы, связанные с регистрацией. Настройка проекта C # на сборку для x86 и (ранее не упоминалось) запуск Visual Studio от имени администратора привели к исчезновению этих функций. Я не думаю, что смог бы создать экземпляр класса во время выполнения без регистрации COM dll.
4. Ну, я подумал, что вы могли бы создать экземпляр своего класса с помощью старой версии интерфейса, зарегистрированной ранее, что могло бы объяснить вашу проблему.