Строитель C++, вызывающий класс VC++
Я скомпилировал библиотеку Hunspell с VC++, которая содержит класс... Теперь я хочу вызвать эту библиотеку в Builder C++ 2006, чтобы использовать ее функции... как я могу это сделать?
Я пробовал с:
typedef Hunspell * (CALLBACK *fpoint)(char *aff_file, char *dict_file);
fp pHunspell = (fp)GetProcAddress(handle_Hunspell, "hunspell_initialize");
if (pHunspell) {
Hunspell* obj = (Hunspell *)pHunspell("..\hunspelldic\en_US.aff", "..\hunspelldic\en_US.dic");
obj->add_dic("..\hunspelldic\it_IT.aff", "..\hunspelldic\it_IT.dic");
}
дело в том, что в BuilderC++ 2006 я могу показывать функции после нажатия клавиши shift-space после obj->, но похоже, что он на самом деле не распознает функции класса и продолжает выдавать Unresolved external '__fastcall Hunspell::add_dic(...);' ссылки из....
Каков будет точный способ вызвать VC++ DLL в Builder C++? Спасибо всем заранее...
Ура, Луиджино
1 ответ
Сначала вы должны #include
файл заголовка импорта для вашей DLL (включая классы, consts определяет...)
после этого есть 2 способа:
статическая DLL-ссылка
это легко, но иногда не работают с MSVC++ DLL. Вам нужно добавить, чтобы спроектировать LIB- файл для вашей DLL, который вы можете создать с помощью implib.exe в папке Borland bin, но вам, вероятно, придется поиграться с переключателями командной строки, чтобы исправить преобразование использованного искажения, пока строитель не сможет разрешить все внешние объекты. например:
implib.exe -c -f -a glut32.lib glut32.dll
если у вас неверный файл lib, компилятор добавит ваши неразрешенные внешние ошибки. Также файлы obj/lib из MSVC++ несовместимы с Borland/Intel, потому что MS использует их нестандартный формат. В таком случае Borland будет кричать что-то вроде неправильного OMF, следовательно, утилита implib
динамическая DLL-ссылка
В приведенном ниже примере я связываю 2 функции из DLL. Для связывания классов вы должны связать все используемые методы всех импортируемых вами классов. Также у вас могут быть проблемы с искажением имен в DLL (аналогично статической ссылке), поэтому используйте какой-нибудь инструмент для изучения dll (я использую DLL Export Viewer), который показывает вам реальные имена функций в DLL, которые вы должны использовать в
GetProcAddress
, Вот пример:HANDLE hdll; typedef BOOL(__stdcall *_InitRemoteCtrl)(HWND); _InitRemoteCtrl InitRemoteCtrl; typedef DWORD(__stdcall *_ReadRemoteData)(); _ReadRemoteData ReadRemoteData; __fastcall TForm1::TForm1(TComponent* Owner):TForm(Owner) { hdll=LoadLibrary("./RemtCtrl.dll"); if (hdll==0) Application->Terminate(); InitRemoteCtrl=(_InitRemoteCtrl)GetProcAddress(hdll,"InitRemoteCtrl"); ReadRemoteData=(_ReadRemoteData)GetProcAddress(hdll,"ReadRemoteData"); } void __fastcall TForm1::FormDestroy(TObject *Sender) { FreeLibrary(hdll); }
Используйте первый вариант, если можете, потому что это безопаснее. Также не забудьте экспортировать / импортировать классы в файле заголовка DLL, экспортировать для источника DLL и импортировать для использования DLL.
class __declspec(dllimport/dllexport) myClass
{
...
};
PS
При построении API между MSVC++ и Borland будьте осторожны при экспорте / импорте, избегайте использования нестандартных типов данных, которые не используются на платформах стендов (или аналогично AnsiString
,...).