问题
I have compiled a Hunspell DLL with VC++ which contains a class... Now I want to call that DLL in Builder C++ 2006 to use its functions...how I can do that?
I tried with:
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");
}
the matter is if in BuilderC++ 2006 I can show functions after pressing shift-space after obj-> but looks like it doesn't really recognize class functions and it keeps giving out Unresolved external '__fastcall Hunspell::add_dic(...);' referenced from....
What would be the exact way to call a VC++ dll into Builder C++? Thanks in advance to everyone...
Cheers, Luigino
回答1:
first you must #include
a import header file for your DLL (including classes, consts defines...)
after that there are 2 ways:
static DLL link
is easy but sometimes do not work with MSVC++ DLLs. You need Add to project a LIB file for your DLL which you can create with implib.exe in Borland bin folder but you probably must play with command line switches to correct convert used mangling until builder can resolve all externals. for example:
implib.exe -c -f -a glut32.lib glut32.dll
if you have incorrect lib file then compiler will add your unresolved external errors. Also obj/lib files from MSVC++ are incompatible with Borland/Intel because MS use their nonstandard format. In such case Borland will shout something like wrong OMF, hence the implib utility
dynamic DLL link
in example bellow I link 2 functions from a DLL. For linking class you must link all used methods of all classes you import. Also you might have problems with name mangling in DLL (similar to static link) so use some tool to explore dll (I use DLL Export Viewer ) which shows you the real function names in DLL which you must use in
GetProcAddress
. Here an example: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); }
Use the first option if you can because it is safer. Also do not forget to export/import classes in the DLL header file export for DLL source and import for DLL usage.
class __declspec(dllimport/dllexport) myClass
{
...
};
PS
While constructing API between MSVC++ and Borland be careful what to export/import avoid the use of non standard data types not used in booth platforms (or in the same way like AnsiString
,...).
来源:https://stackoverflow.com/questions/13123737/builder-c-calling-vc-class