DLL from Visual C++ in Borland C++?

We are using Borland C++. Unfortunately, there is one DLL
created with Microsoft Visual C++ that we have to use and we
can't seem to link it into our application. We don't have the source for it. The DLL is created for use with Visual Basic. I don't know whether this makes it unusable for C++ or not, but we can't find the symbols in it. I have tried creating an import library using IMPLIB, but that library doesn't help. I get "Unresolved external" on each referenced function in the DLL, even though I link in the import library.

When I try to look at the contents of the DLL using the tool
LIB in Microsoft Visual C++ 5.0, it says that the library is
corrupted. However, the DLL works fine with both Visual Basic and PowerBuilder. I think the DLL is created using an earlier version of Visual C++, like 4.x.

I have created a dummy file with stubs of the same functions
as in the DLL and built a dummy DLL using Borland C++ 5.01.
When I use that, it works. When I compare the TDUMP output
for the two DLLs (my dummy and the original), the output
differs significantly. My DLL contains the function names
including the arguments, but the original DLL contains only
the function names. Could the original DLL have been created
using a different calling convention, like PASCAL or something? Does that make it unusable in C++? Shouldn't the arguments be there anyway?

I have also built my dummy DLL using Visual C++ 5.0, but the
resulting import library is not accepted by Borland C++. I
have seen that some people deliver two different import
libraries with their DLLs, one for Visual C++ and one for
Borland C++. The question is if it's possible to create an
acceptable import library without building the DLL in Borland C++, but instead using the existing DLL built by Visual C++.
--
--Ulrik Sandberg, lmiusg@eei.ericsson.se

ulsaAsked:
Who is Participating?
I wear a lot of hats...

"The solutions and answers provided on Experts Exchange have been extremely helpful to me over the last few years. I wear a lot of hats - Developer, Database Administrator, Help Desk, etc., so I know a lot of things but not a lot about one thing. Experts Exchange gives me answers from people who do know a lot about one thing, in a easy to use platform." -Todd S.

RONSLOWCommented:
There are great differences in calling conventions (and function naming) between Borland and MS.  These are bad enough when using C - but get even worse with C++ (due to name mangling etc).

I assume you do not have the source to this DLL and/or you didn't develop it yourself.

However, if you ARE writing DLL's yourself, I'd suggest you look at using COM because it is a binary standard which addresses all the parameter passing and naming problems that raw DLL's have and is portable across languages.  Don't get confused - COM itself isn't all that complicated - you don't need to write full OLE servers or custom controls - but it is a very nice way of encapsulating functionality within a DLL or EXE and is also nice in that it helps with versioning and allows you to call in-process, out-of-process or remote in exactly the same way.



0
ulsaAuthor Commented:
I didn't develop it myself and I don't have the source.

What I don't understand is why Borland's IMPLIB doesn't find the relevant information for building an import library. Even if the name mangling is different, shouldn't Borland have figured it out by now? It doesn't make sense, because the DLL works for Visual Basic and PowerBuilder.
0
ulsaAuthor Commented:
Adjusted points to 100
0
Keep up with what's happening at Experts Exchange!

Sign up to receive Decoded, a new monthly digest with product updates, feature release info, continuing education opportunities, and more.

lwidingCommented:
You do not mention if you have a header file that was supplied with the DLL or if you created your own. What you have described sounds very much like your C++ code is looking for mangled function names, but the DLL is using the standard Windows naming conventions of just the function name.

If your link errors are looking for a function like "void fna(int)", than you need to add the following to your header file:

extern "C" {
// rest of header file, externs for DLL functions
}

You should also define the functions using the WINAPI type which should be defined in the windows.h file. This should define the funtions to use the pascal naming convention, and avoid the C++ style name mangling.
0
ulsaAuthor Commented:
I used a header file that was delivered with the UNIX version of the library. I'm afraid I can't "define" stuff, since I don't have the source code. Let me rephrase the question somewhat:

a) If a DLL is created "for Visual Basic" (whatever that means), does that make the DLL unusable for a C++ application?

b) Can I trick the linker to find the functions in a DLL "for Visual Basic" by using 'extern "C"'?

c) Could bugs in Borland C++ 5.01 IMPLIB play a part in this problem?
0
y96andhaCommented:
Could you send me a copy of the DLL and header file so I could try and create an import library for it?

The problem with the DLL seems to be that the names in it are not mangled (does not contain function parameters). The normal solution for this is to use extern "C" before each function declaration. This will tell your C++ compiler not to expect mangled function names from the DLL, just like Visual Basic defaults to.

You could also consider using a module definition file with IMPORTS statements for all functions in the DLL. This should also be a possible solution.

If all else fails you could finally resort to loading the dll manually with LoadLibrary.

Hälsningar / y96andha@cyd.liu.se
0

Experts Exchange Solution brought to you by

Your issues matter to us.

Facing a tech roadblock? Get the help and guidance you need from experienced professionals who care. Ask your question anytime, anywhere, with no hassle.

Start your 7-day free trial
lwidingCommented:
In answer to your questions:

a) Generally, such a DLL can be used with any language.

b) using extern "C" and WINAPI in the header file, like I mentioned in my previous post, should be enough to tell your compiler to generate the proper external names for the linker to connect to the DLL, as well as using the correct calling conventions to properly call those functions.

c) I do not think the problem is in the Borland IMPLIB, but in the naming conventions. You need to get Borland C++ to generate the names used by the DLL, and this requires the use of the extern "C" and either the WINAPI type or __pascal type in the extern statement for the functions.

For example, if one of the functions in the DLL is defined as:
int DllFunc1(int x);
you should change the definition in the header to:
extern "C" int WINAPI DllFunc1(int x);

This is what I meant by defining the functions before, that you may need to modify the header file you got in order to make this work.

If you still get an error from the linker saying that DllFunc1 is not found, than you need to either turn off type sensitivity in the link, or use IMPDEF to create a .DEF file form the DLL, modify it, and use IMPLIB to build the proper .LIB file. The modifications to the .DEF file would be as follows:

For each line like this:
   DLLFUNC1 @1
add a line like this:
   DllFunc1=DLLFUNC1

0
ulsaAuthor Commented:
lwiding's first answer wasn't clear enough for me to accept it. However, if I had requested a clarification instead of rejecting his/her answer, I would have given the answer the highest marks. The comment that followed proved to be exactly what was needed, but then another expert was already involved. I apologize for this and blame the turbulent situation I was in, together with the fact that I'm new to this forum.

The other expert's answer was also correct. I managed to solve the problem and I am very grateful for that. I don't see any other solution than to give the points to the second expert.

The correct answer is as follows:
--------------------------------
My header file contained function declarations using the standard UNIX calling convention:

int myFunc(int myArg, char *anotherArg);

All that was needed in order to access the functions in the DLL was the following change:

extern "C" int WINAPI
myFunc(int myArg, char *anotherArg);

0
It's more than this solution.Get answers and train to solve all your tech problems - anytime, anywhere.Try it for free Edge Out The Competitionfor your dream job with proven skills and certifications.Get started today Stand Outas the employee with proven skills.Start learning today for free Move Your Career Forwardwith certification training in the latest technologies.Start your trial today
Microsoft Development

From novice to tech pro — start learning today.