Товарищи, есть проблема следующего характера.
У меня есть легаси-код, из которого мне требуется сделать СОМ-сервис. Использую для этого дела класс, отнаследованный от CComModule. В результате при компиляции получаю ошибку вида:
error LNK2019: unresolved external symbol "public: void * __thiscall ATL::CAtlBaseModule::GetHInstanceAt(int) referenced in function "void * __cdecl ATL::AtlFindStringResourceInstance(unsigned int,unsigned short)"
К сожалению, в гугле нашел пока только одну ссылку на такую проблему, и то без решения. Подскажите пожалуйста, в чем тут проблема и как ее решить.
Здравствуйте, Glоbus, Вы писали: G>Использую для этого дела класс, отнаследованный от CComModule.
Как именно Вы его используете?
"Дайте мне возможность выпускать и контролировать деньги в государстве и – мне нет дела до того, кто пишет его законы." (c) Мейер Ансельм Ротшильд , банкир.
Здравствуйте, Rakafon, Вы писали:
R>Здравствуйте, Glоbus, Вы писали: G>>Использую для этого дела класс, отнаследованный от CComModule.
R>Как именно Вы его используете?
Код (в урезанном виде — только основное) выглядит так:
CServiceModule _Module;
BEGIN_OBJECT_MAP(ObjectMap)
OBJECT_ENTRY(CLSID_CoCVShell, CCVShell)
END_OBJECT_MAP()
extern"C"int WINAPI _tWinMain(HINSTANCE hInstance, HINSTANCE /* hPrevInstance */,
LPTSTR lpCmdLine, int/* nShowCmd */)
{
g_hInst = hInstance;
_Module.Init( ObjectMap, hInstance, IDS_SERVICENAME );
_Module.m_bService = TRUE;
TCHAR szTokens[] = _T("-/");
TCHAR *szContext;
LPTSTR lpszToken = _tcstok_s(lpCmdLine, szTokens, &szContext);
while (lpszToken != NULL)
{
if (_tcsicmp(lpszToken, _T("UnregServer"))==0)
return _Module.UnregisterServer();
if (_tcsicmp(lpszToken, _T("RegServer"))==0)
return _Module.RegisterServer(TRUE);
if (_tcsicmp(lpszToken, _T("Embedding"))==0)
_Module.m_bService = FALSE;
if (_tcsicmp(lpszToken, _T("LocalServer"))==0)
{
_Module.SetupAsLocalServer( hInstance );
return 0;
}
lpszToken = _tcstok_s(NULL, szTokens, &szContext);
}
_Module.Start();
// When we get here, the service has been stoppedreturn _Module.m_status.dwWin32ExitCode;
}
Здравствуйте, Rakafon, Вы писали:
R>Здравствуйте, Glоbus, Вы писали: G>>Использую для этого дела класс, отнаследованный от CComModule.
R>Как именно Вы его используете?
Код CServiceModule специально взял из работающего примера
Здравствуйте, Glоbus, Вы писали: G>Код (в урезанном виде — только основное) выглядит так: G>Код CServiceModule специально взял из работающего примера
Та не все эти простыни значения не имеют. Я имею в виду от кого кто наследуется, что с ним делают в точке входа, какие хидеры врубаются и т.д. Я как-то сразу не обратил внимания, что вы наследуетесь от CComModule. Зачем вы наследуетесь от него?
An instance of CAtlBaseModule named _AtlBaseModule is present in every ATL project, containing a handle to the module instance, a handle to the module containing resources (which by default, are one and the same), and an array of handles to modules providing primary resources. CAtlBaseModule can be safely accessed from multiple threads.
This class replaces the obsolete CComModule class used in earlier versions of ATL.
Впрочем вряд ли проблема в CComModule, но ЕМНИП, то для проектов сервисного типа используется CAtlServiceModuleT как базовый. Вот его лучше и пользовать как базу для своего модуля, ну чиста технической правильности проекта ради :)))
У меня такое ощущение, что у вас вообще не atl-евский проект: глобальная переменная _AtlBaseModule определена в файле atlbase.inl или atlbase.cpp, там же и реализации методов AddResourceInstance, RemoveResourceInstance, GetHInstanceAt и конструктора/деструктора. Чтобы "получить" эту имплементацию надо или статически или динамически слинковаться с библиотекой ATL. Ваши unresolved external symbol'ы могут появиться только, если не слинковаться с ATL. Любой ATL-евский проект сам включает эту опцию. Что у вас в опции "Project -> Properties -> Configuration Properties -> General -> Use of ATL" пробито? Если динамическая линковка, то понятно потребная вам функция будет в ATLXX.dll, если статическая то реализация недостающего вам метода будет валяться в atlbase.inl, который автоматом будет включен файлом atlbase.h, если не стоит опция "Dynamic Link to ATL", т.е. если не будет макроса _ATL_DLL определено. Хидеры atlbase.h и atlcore.h включены в sdtafx'е?
Я бы на вашем месте вообще создал бы сервис с нуля, а ля Hello World COM-Service с фейковым интерфейсом и имплементацией выводящей мессаджбокс с дурацким текстом, чтобы убедиться что всё пашет, а затем переносил бы туда существующий легаси-код с интерфейсами.
Удачи!
"Дайте мне возможность выпускать и контролировать деньги в государстве и – мне нет дела до того, кто пишет его законы." (c) Мейер Ансельм Ротшильд , банкир.
Ну что, Glоbus, получилось у вас зарезолвить недостающие реализации методов класса CAtlBaseModule?
"Дайте мне возможность выпускать и контролировать деньги в государстве и – мне нет дела до того, кто пишет его законы." (c) Мейер Ансельм Ротшильд , банкир.
Здравствуйте, Rakafon, Вы писали:
R>Здравствуйте, Glоbus, Вы писали: G>>Код (в урезанном виде — только основное) выглядит так: G>>Код CServiceModule специально взял из работающего примера
R>Та не все эти простыни значения не имеют. Я имею в виду от кого кто наследуется, что с ним делают в точке входа, какие хидеры врубаются и т.д. Я как-то сразу не обратил внимания, что вы наследуетесь от CComModule. Зачем вы наследуетесь от него?
R>http://msdn.microsoft.com/en-us/library/bwfd57ew%28VS.80%29.aspx
R>
An instance of CAtlBaseModule named _AtlBaseModule is present in every ATL project, containing a handle to the module instance, a handle to the module containing resources (which by default, are one and the same), and an array of handles to modules providing primary resources. CAtlBaseModule can be safely accessed from multiple threads.
R>This class replaces the obsolete CComModule class used in earlier versions of ATL.
Да, я знаю что он обсолит, но решил сделать так... по старинке
R>Впрочем вряд ли проблема в CComModule, но ЕМНИП, то для проектов сервисного типа используется CAtlServiceModuleT как базовый. Вот его лучше и пользовать как базу для своего модуля, ну чиста технической правильности проекта ради
R>У меня такое ощущение, что у вас вообще не atl-евский проект: глобальная переменная _AtlBaseModule определена в файле atlbase.inl или atlbase.cpp, там же и реализации методов AddResourceInstance, RemoveResourceInstance, GetHInstanceAt и конструктора/деструктора. Чтобы "получить" эту имплементацию надо или статически или динамически слинковаться с библиотекой ATL. Ваши unresolved external symbol'ы могут появиться только, если не слинковаться с ATL. Любой ATL-евский проект сам включает эту опцию. Что у вас в опции "Project -> Properties -> Configuration Properties -> General -> Use of ATL" пробито?
Там стоит "Dynamic Link...". Хотя можно ставить и статик — это ситуацию не меняет — все равно кидает анрезолвед экстёрнал.
R>Если динамическая линковка, то понятно потребная вам функция будет в ATLXX.dll, если статическая то реализация недостающего вам метода будет валяться в atlbase.inl, который автоматом будет включен файлом atlbase.h, если не стоит опция "Dynamic Link to ATL", т.е. если не будет макроса _ATL_DLL определено. Хидеры atlbase.h и atlcore.h включены в sdtafx'е?
Да, включены, но не в stdafx, в других файлах.
R>Я бы на вашем месте вообще создал бы сервис с нуля, а ля Hello World COM-Service с фейковым интерфейсом и имплементацией выводящей мессаджбокс с дурацким текстом, чтобы убедиться что всё пашет, а затем переносил бы туда существующий легаси-код с интерфейсами.
Да, я собственно наверное так и сделаю щас
R>Удачи! R>
Здравствуйте, Rakafon, Вы писали:
R>Ну что, Glоbus, получилось у вас зарезолвить недостающие реализации методов класса CAtlBaseModule?
Ну как я уже говорил, если создать новый, изначально АТЛ-ный прожект, то все пашет нормально Вот сейчас в него легаси перетаскиваю — там просто код 25-летней давности (и это нифига не шутка! таки реально 25 лет!) с кучей всякого мусора, так что приходится чуток исхитряться
Здравствуйте, Glоbus, Вы писали: G>Ну как я уже говорил, если создать новый, изначально АТЛ-ный прожект, то все пашет нормально :) Вот сейчас в него легаси перетаскиваю — там просто код 25-летней давности (и это нифига не шутка! таки реально 25 лет!) с кучей всякого мусора, так что приходится чуток исхитряться :)
ГЫ :)
"Дайте мне возможность выпускать и контролировать деньги в государстве и – мне нет дела до того, кто пишет его законы." (c) Мейер Ансельм Ротшильд , банкир.