Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Как собрать dll на Си, использующую другую dll на С++?  (Прочитано 12175 раз)
0 Пользователей и 2 Гостей смотрят эту тему.
Michaelss
Гость
« : 08-02-2006 15:38 » 

Следующая проблема:
Есть модули на Си для сборки dll и нужно в одном из модулей вызывать методы различных интерфейсов, реализованных объектами библиотеки COM, написанной на C++(имеются её .h файлы и dll). Т.е. dll написанная на Си обращается к dll написанной на С++. Не могли ли вы описать "подводные камни" процесса подключения и сборки такого проекта в шестой студии. Он у меня собирается как Release, но dll не подгружается в использующую её программу.
Записан
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #1 : 08-02-2006 16:56 » 

COM интерфейс не зависит от языка реализации.  С технической точки зрения это только массив указателей на функции. 

Но я удивлён тем, что вы делаете вызовы СОМ непосредственно из Си.  Массив функциональных указателей интерфейса СОМ устроены таким образом, что совпадает с устройством таблицы виртуальных функций, генерируемой MS VС++, поэтому в Си++ для вызова метода надо кастировать указатель на интерфейс к нужному типу и просто вызвать метод черед указатель.  Это проще и безопаснее, чем вызывать функцию по смещению в массиве указателей, как требуется делать в Си.
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
Michaelss
Гость
« Ответ #2 : 08-02-2006 17:13 » 

 А что насчет настроек среды VS? После сборки dll я открываю её в Dependecy Walker и там нет экспортируемы функцйий. Может надо в файле .def их описать?
Записан
Артем
Опытный

nz
Offline Offline
Пол: Мужской
Beware the wolf in sheep's clothing.


« Ответ #3 : 08-02-2006 18:27 » 

Но я удивлён тем, что вы делаете вызовы СОМ непосредственно из Си. 
Я тоже удивляюсь, что подобные вещи приходиться делать на "голом" Си... но  тоже делаю, потому что, например, такие требования моего програмистского начальства Не надо


Michaelss, насколько я знаю в .def интерфейсные функции описывать не надо.

  Правильно ли я понял, что уже есть некий СОМ-объект к функциям которого не получается обратиться из модуля написанном на "чистом" Си? Если да, то покажи как ты получаешь указатели на интерфейсные функции Сом-объекта
 

Записан
Артем
Опытный

nz
Offline Offline
Пол: Мужской
Beware the wolf in sheep's clothing.


« Ответ #4 : 09-02-2006 07:44 » 

 Наверное должно быть что то вроде:


Считаем что есть СОМ объект MyObject, у которого есть интерфейсная функцмя HelloPrint, и в нашем модуле нужно вызвать эту функцию.

Можно сделать так:
// получаем интерфейс объекта MyObject
  if( (r = CoCreateInstance( &CLSID_MyObject, NULL, CLSCTX_INPROC_SERVER, &IID_IMyObject, (void **)&ObjectManager )) != S_OK )
  {     
   MessageBox (NULL, "Невозможно создать экземпляр объекта", "Error", MB_OK);
   return 1;
  } 
  // Вызываем HelloPrint, причем первый параметр должен указывать на объект (в С++ этот указатель -- this--передается неявно)
  if(ObjectManager->lpVtbl->HelloPrint( ObjectManager, ... ) != S_OK )
   {
      MessageBox (NULL, "Ошибка HelloPrint", "Error", MB_OK);
        return 1;      
   }
   
   
где:
IMyObject *MyObject;

IMyObject должен быть определен в СОМ-объекте.
 
На"чистом" С это может выглядеть например:

#define INTERFACE IMyManager

DECLARE_INTERFACE( IMyManager )
{
  STDMETHOD( QueryInterface )( THIS_ REFIID riid, void **ppi ) PURE;
  STDMETHOD_( unsigned long, AddRef )( THIS ) PURE;
  STDMETHOD_( unsigned long, Release )( THIS ) PURE; 
  STDMETHOD( HelloPrint ) ( THIS_ const GUID *object_id, REFIID interface_id, void **pointer ) PURE;   
};

макроопределения см. ObjBase.h в инклюдах VS.
Записан
npak
Команда клуба

ru
Offline Offline
Пол: Мужской

« Ответ #5 : 09-02-2006 11:08 » new

DLL с реализацией COM объектов должна экспортировать только 5 функций
    DllMain
    DllRegisterServer
    DllUnregisterServer
    DllCanUnloadNow
    DllGetClassObject
Интерфейсные функции не экспортируются
Записан

UniTesK -- индустриальная технология надежного тестирования.

http://www.unitesk.com/ru/
Michaelss
Гость
« Ответ #6 : 09-02-2006 11:16 » 

Спасибо! Кажется я разобрался!!!
 Я подключаю библиотеку и вот текст из её хелпа:

В программе на C++ использование библиотеки Morphology Engine сводится к вызову методов различных интерфейсов, реализованных объектами библиотеки. Описания интерфейсов находятся в заголовочном файле Morpho.h. Этот файл должен включаться в каждый модуль, содержащий обращения к методам библиотеки Morphology Engine. С каждым интерфейсом связан уникальный идентификатор (IID). Определения уникальных идентификаторов расположены в файле Morpho_i.c. Этот файл должен включаться только в один из модулей программы, использующей библиотеку Morphology Engine.

Любое приложение, использующее библиотеку Morphology Engine, должно предварительно инициализировать библиотеку COM. Это делается с помощью функции CoInitialize. При завершении работы приложения необходимо вызвать функцию CoUninitialize. Обе эти функции объявлены в заголовочном файле objbase.h.

После инициализации библиотеки COM можно обращаться к функции CoCreateInstance для создания основного объекта библиотеки Morphology Engine. В качестве параметров этой функции необходимо передать уникальные идентификаторы класса и интерфейса к объекту. В заголовочном файле Morpho.h объявлены константы CLSID_MorphoEngine и IID_IMorphoEngine. В результате работы функции CoCreateInstance будет получен указатель на интерфейс IMorphoEngine – основной интерфейс библиотеки Morphology Engine. Приложение, использующее библиотеку Morphology Engine, выглядит следующим образом:
Код:
#include <objbase.h>
#include <morpho.h>
#include <morpho_i.c>

void main()
{
// Инициализация библиотеки COM
CoInitialize(0);
IMorphoEngine* pMorphoEngine;
// Создание основного объекта библиотеки Morphology Engine
CoCreateInstance( CLSID_MorphoEngine, 0,
CLSCTX_INPROC_SERVER, IID_IMorphoEngine, (LPVOID*) &pMorphoEngine );
// Далее идет собственно код программы, использующий pMorphoEngine
…………………………
// Освобождаем основной объект
pMorphoEngine->Release();
// Деинициализация библиотеки COM.
CoUninitialize()
}
[/color]

 Нужно было просто разобраться с типом импортируемых функций WEXPORT_FTYPE, который задефайнен как _stdcall если не определена директива препроцессора WIN32_DLL_VSN, которая как раз и говорит что бы функции экспортировались.

А на Си приходится писать, т.к. еа нём представлен SDK программы к которой я добавляю функционал.
ВСЕМ СПАСИБО!!!!
Записан
Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines