I am trying to use Adobe's FDF Toolkit to generate a FDF file to populate a PDF. I have their .h, .lib, and. dll are have put them all in the correct places; they are all in my path. However, when I compile my cpp, I get linking errors:
Why is this? The library is there, it just isn't recognizing it.
I am using IBM's Visual Age C++ on a WinNT System. Could there be a problem that the adobe libs were compiled with a different c++ compiler than me? Maybe I'm not linking correctly? Maybe I'm not compiling correctly? Is it case sensitive?
Originally posted by Jen P
Could there be a problem that the adobe libs were compiled with a different c++ compiler than me?
I guess that if this was the case, your linker would warn you that it doesn't understand the library format. Just a guess, though, as I don't know IBMs compiler.
Gabriel, CodeGuru moderator
Forever trusting who we are
And nothing else matters - Metallica
If the library was created with object files created from a C++
compiler, then you would get the mangled functions in your library
and then your C++ compiler might not be able to understand
them.
However, if the library file was created by a C compiler, then it's
my guess that your compiler is compiling the functions as if they're
C++ functions [complete with mangling] and that is why the linker
cannot find them. So, try doing wrapping the header file you're
#include'ing with extern "C"; if you cannot modify the given
header file, I think you can include another one that does the
extern for you:
I'm not sure about that above "code"; I don't know how the
preprocessor #include woudl be included AFTER the extern was
referenced.... So, if the above doesn't work, then just edit the
header file you have and add the extern "C" manually.
Originally posted by Jen P
I am trying to use Adobe's FDF Toolkit to generate a FDF file to populate a PDF. I have their .h, .lib, and. dll are have put them all in the correct places; they are all in my path. However, when I compile my cpp, I get linking errors:
Why is this? The library is there, it just isn't recognizing it.
I am using IBM's Visual Age C++ on a WinNT System. Could there be a problem that the adobe libs were compiled with a different c++ compiler than me? Maybe I'm not linking correctly? Maybe I'm not compiling correctly? Is it case sensitive?
Any help would be greatly appreciated.
You say you have the ".lib" file, but do you know which compiler produced the file? Import libraries are compiler dependent, so a VC++ lib file may not work for an IBM compiler. I know a VC++ lib file will not work for a C++ Builder or Borland compiler.
To get around these issues, your best bet is to forget about the lib file and use the tried and true method that works all the time -- and that is to use LoadLibrary and GetProcAddress. If you are not familiar with these functions, basically LoadLibrary loads the DLL at runtime, and GetProcAddress returns a function pointer to one of the exported functions. So in your case, if the Adobe Library is called ADOBE32.DLL, and the function is FDFSetFile which takes one LPCSTR parameter and returns an int, this will work:
Code:
#include <windows>
typedef int (*FDFSETFILEFUNC)(LPCSTR);
int main()
{
FDFSETFILEFUNC pFunc=NULL;
HMODULE hMod = LoadLibrary( "ADOBE32" );
if ( hMod )
{
pFunc = (FDFSETFILEFUNC)GetProcAddress("FDFSetFile");
if (pFunc)
{
// Call the FDFSetFile function
(*pFunc)("Test");
}
else
{
// Exported function called "FDFSetFile" does not exist
}
// Free the library when done
FreeLibrary( hMod );
}
else
{
// Library could not load
}
}
Of course, this is just an illustration of just calling one function. There are C++ classes that you can find on the net that encapsulate the LoadLibrary / GetProcAddress / FreeLibrary approach to handling DLL's.
This is how my company tests the DLL's we create against different C++ compilers. Instead of wasting time trying to figure out how each compiler handles .lib files, all we need to do is to compile the code with no .lib file and everything falls into place.
You should load the Adobe DLL into Dependency Walker or some other utility that lists the exported functions. When you use GetProcAddress, your function name must match exactly (including case-sensitivity) with the name that is exported from the DLL. If not, GetProcAddress will return NULL.
Originally posted by Jen P
Thanks so much for all your suggestions. I tried them all; the last post from Paul McKenzie worked!!
However, when I run my executable, I get errors. Does anyone know how I can look into these problems?
Ok. Let us know where the error occurs. Is it when you make a call to a DLL function? If so, is it the first call to the DLL?
The reason why I ask is that you may have to declare your function pointers a little differently. I'm assuming that the Adobe functions are __stdcall (check the header file for the function prototypes). If so, your function pointer signatures should be declared with the __stdcall modifier also. If the failure appeared with the very first DLL call, this is a good indication that either the function wasn't declared properly, or (of course) you just didn't call your function correctly
Use the Dependency Walker utility (hopefully you have this program that allows you to look into a DLL's exported functions). I believe you can get it free on the Internet if you don't have it (or programs similar to Dependency Walker). You need to establish whether the functions are stdcall or cdecl (the other calling convention). If they are stdcall, then you need to change the prototype of the function pointers to the following:
I walked though the debug and found that it only has problems with 3 of the 5 functions called. FDFCreate and FDFSetValue are ok. I've attached my cpp and the loaded library's header file.
I have never used Dependency Walker before, but I have downloaded it now and will look into it. When I run it in Dependency Walker, this is the last thing it shows in the log view:
Second chance exception 0xC0000005 (Access Violation) occurred in "FDFTK.DLL" at address 0x10010209.
Exited "U13PDFRPT.EXE" (process 0x179) with code 128 (0x80).
Not really sure what to do with that information.
Thanks.
Last edited by Jen P; March 3rd, 2003 at 12:56 PM.
Are you sure the Create is working? You are getting a pointer to a new FDFDoc returned?
And the typedefs should read:
Code:
typedef int (__stdcall *FDFCREATEFUNC)(FDFDoc);
typedef int (__stdcall *FDFSETFILEFUNC)(FDFDoc, LPCSTR);
typedef int (__stdcall *FDFSETVALUEFUNC)(FDFDoc, LPCSTR, LPCSTR, BOOL);
typedef int (__stdcall *FDFSAVEFUNC)(FDFDoc, LPCSTR);
typedef int (__stdcall *FDFCLOSEFUNC)(FDFDoc);
Originally posted by Mick_2002
And the typedefs should read:
Code:
typedef int (__stdcall *FDFCREATEFUNC)(FDFDoc);
typedef int (__stdcall *FDFSETFILEFUNC)(FDFDoc, LPCSTR);
typedef int (__stdcall *FDFSETVALUEFUNC)(FDFDoc, LPCSTR, LPCSTR, BOOL);
typedef int (__stdcall *FDFSAVEFUNC)(FDFDoc, LPCSTR);
typedef int (__stdcall *FDFCLOSEFUNC)(FDFDoc);
Thanks Mick_2002. I knew the __stdcall went somewhere, but didn't remember exactly where. We wrap all of this junk in macros, and I didn't have the source handy, so I guessed (wrong).
* The Best Reasons to Target Windows 8
Learn some of the best reasons why you should seriously consider bringing your Android mobile development expertise to bear on the Windows 8 platform.