Solved

How to use DLL again

Posted on 1997-06-13
10
355 Views
Last Modified: 2008-02-26

Hi,

I have a Borland C++ DLL "testapi.dll", now I want to use it in Visual C++ project. I did as following:

1)use "impdef testapi testapi.dll" got a "testapi.def" (The  "impdef" is a Broland command).
2)use "\msdev\bin\lib: /def:testapi.def" got a "testapi.lib"

Then I added the testapi.lib file into my project. The problem is:

The funtion I defined in the testapi.dll is "CreatTestWindow", when I built the VC++ project, there is a linker error, "unresolved function _CreatTestWindow". I don't know why there is an extra "_". Does that because my conversion is not correct?

Thanks.  
0
Comment
Question by:Gina060497
  • 5
  • 4
10 Comments
 
LVL 23

Expert Comment

by:chensu
Comment Utility
In your testapi.h, you may declare the function like this:
int CreatTestWindow(DWORD dwParam);

Your project contains the CPP files, so it uses C++ linkage by default but your testapi.dll uses C linkage. Change your declaration to:

extern "C" int CreatTestWindow(DWORD dwParam);

Or, as most of the standard header files,

#ifdef __cplusplus
extern "C" {
#endif

...

#ifdef __cplusplus
}
#endif

0
 

Author Comment

by:Gina060497
Comment Utility
Thanks very much for Chensu's help. Actually I already defined " extern "C" int CreatTestWindow(DWORD dwParam)", I also used
                  #ifdef __cplusplus
                  extern "C" {
                  #endif
But the error is still there.

Now my testapi.dll contains the CPP files, but my project only uses C files. I already added
                  #ifdef __cplusplus
                  extern "C" {
                  #endif
into my project head files.

When I view the "testapi.def", the function "CreatTestWindow" is there as an export function. But when I view the "testapi.lib", the function changed to "_CreatTestWindow". Can anyone tell me what happened?

Thank you very much for your help.

 
0
 
LVL 23

Expert Comment

by:chensu
Comment Utility
When you built your testapi.dll, did you add extern "C"? You need to build the DLL using C linkage.

The reason that the function is changed to "_CreatTestWindow" is that the compiler and linker use this convention for internal use. It always adds the extra "_" before the function names.
0
 

Author Comment

by:Gina060497
Comment Utility
Yes, I added extern "C" when I built "testapi.dll". The error message is "unresolved function _CreatTestWindow@20". Then I added "CreatTestWindow@20" into my "testapi.def", used "\msdev\bin\lib /def:testapi.def" to recreat the testapi.lib. There is not liker error after that. But the problem is I can't call the function "CreatTestWindow", whenever I called it in my VC project, there are some problems. The reason seems still because of the Borland C++ "testapi.dll".

Thank you very much for your help.

 
0
 
LVL 23

Expert Comment

by:chensu
Comment Utility
I think the problem is related to the calling convention. Add WINAPI to the function prototype (for the DLL and the VC project) to use the pascal calling convention on both sides.

extern "C" int WINAPI CreatTestWindow(DWORD dwParam);

And, you may need to add a space between CreatTestWindow and @20.

BTW, I am not sure if Borland C++ define the WINAPI macro. If not, you can check Microsoft version.
0
6 Surprising Benefits of Threat Intelligence

All sorts of threat intelligence is available on the web. Intelligence you can learn from, and use to anticipate and prepare for future attacks.

 

Author Comment

by:Gina060497
Comment Utility
Here is my "testapi.cpp" and "testapi.h": (and also,when I changed "CreatTestWindow@20" to "CreatTestWindow @20", the error of "unresolved function "CreatTestWindow@20" comes again).

I saw a note in the microsoft knowledge base Q131313:
"This method (import Libraries without .objs or source) may not work with DLLs generated with non_Microsofe development tools." Could that be reason of the problem?

Thanks

TESTAPI.CPP
======================
#include <owl/window.h>
#include <owl/module.h>
#include <windows.h>

static TModule* g_ResMod;
static TModule* g_BwccMod;

#ifdef WIN32
      BOOL WINAPI
      DllEntryPoint(HINSTANCE hInstance, DWORD dwReason, LPVOID lpReserved)
      {
            if (dwReason == DLL_PROCESS_ATTACH)
            {
                  //if (!g_ResMod) {
                  //      g_ResMod = new TModule(0, hInstance);
                  //      g_BwccMod =  new TModule ("bwcc.dll");
                  //}
            }
            else
            if (dwReason == DLL_PROCESS_DETACH)
            {
            }

            return 1;  // ok
      }
#else

extern "C"
int FAR PASCAL LibMain (HINSTANCE hInstance, WORD wDataSeg, WORD cbHeapSize, LPSTR lpCmdLine) {
       if (!g_ResMod) {
            g_ResMod = new TModule(0, hInstance);
            g_BwccMod =  new TModule ("bwcc.dll");
      }
      if (cbHeapSize > 0)
            UnlockData(0);
       return true;
}

#endif

static TWindow* g_pwndParent = 0;
static TWindow* g_testWnd = 0;

extern "C" void WINAPI _export Function() {

}

extern "C"
//void  _export CreateTestWindow() {
 void WINAPI _export CreateTestWindow(HWND hwndParent, WORD x, WORD y, int wd, int ht) {

/*      g_pwndParent = new TWindow ( hwndParent, g_ResMod );
      g_testWnd = new TWindow ( g_pwndParent, 0, g_ResMod );
      g_testWnd->Attr.Style |= WS_CHILD | WS_VISIBLE | WS_BORDER;
      g_testWnd->Attr.X = 0;
      g_testWnd->Attr.Y = 0;
      g_testWnd->Attr.W = 100;
      g_testWnd->Attr.H = 100;

   */

      MessageBox ( NULL, "CreateTestWindow called\n", "TestApi", MB_OK );

   }

extern "C"
//void _export DestroyTestWindow() {
void WINAPI _export DestroyTestWindow() {
/*
      g_pwndParent->Destroy();
      delete g_pwndParent;

   */

      MessageBox ( NULL, "DestroyTestWindow called\n", "TestApi", MB_OK );

}

TESTAPI.H
==========================
#ifndef _TESTAPI_H_
#define _TESTAPI_H_

#ifdef __cplusplus
extern "C"
{
#endif

void WINAPI _export CreateTestWindow(HWND hwndParent, WORD x, WORD y, int wd, int ht);

#ifdef __cplusplus
};
#endif

#endif      //_TESTAPI_H_
0
 
LVL 23

Expert Comment

by:chensu
Comment Utility
Hi, I am here again.

Yes, I think that is the reason. ("This method (import Libraries without .objs or source) may not work with DLLs generated with non_Microsofe development tools.") Borland C++ 5.01 has the implib.exe for 32-bit DLLs. Try that one.
0
 

Author Comment

by:Gina060497
Comment Utility
I used "implib.exe" to import the testapi.lib. The error was " testapi.lib: fatal error LNK1136: invalid or corrupt file." I tried again using "\bc5\bin\implib testapi testapi.dll" just now, still the same error.

"Could anyone tell me how to use Borland C++ DLL files in VC 4.00?" :)

Thank you very much for your help.

Gina



0
 
LVL 4

Accepted Solution

by:
md041797 earned 50 total points
Comment Utility
This is from Ron Burk's column in Win Dev Jrn, Aug 96:

VC++'s Missing Import Utility
Yet another new inconvenience that the 32-bit Visual C++ offers is the inability to create import libraries directly from DLLs. In the past, Microsoft (like all other Windows compiler vendors) provided a utility that, given an arbitrary DLL, would create an import library so you could link implicitly with that DLL. Incredibly, the 32-bit version of Visual C++ no longer offers such a utility; Microsoft's 32-bit link.exe can create an import library when it links your object code, but can't create an import library from just the DLL itself. In a Knowledge Base note (PSS ID Number Q131313), Microsoft offers two alternatives. One only works with __cdecl functions. The other requires that you to make a dummy DLL with Visual C++ that has stubs for all the entry points in the target DLL, and then generate an import library from that fake DLL of stubs. Customers will not be happy if you hand them a DLL and tell them to jump through these hoops to make it work with Visual C++.
 
If you must ship a DLL that can be implicitly linked with Microsoft's compiler, it looks like you actually have to buy a copy of Visual C++ and use it just to generate a Microsoft import library (unless you care little for your end user's convenience). As you might expect, Borland C++ still includes a utility to generate an import library from a DLL. For example, if someone hands you a Microsoft-compiled DLL called dll.dll, all you have to do is type
 
implib dll.lib dll.dll
 
to create a Borland import library for it. Borland and Microsoft use incompatible formats for their import libraries, so the Borland .lib file will not work with Microsoft's compiler or vice versa.


MS Knowledge Base is at www.microsoft.com/kb.
Hope this helps.
0
 

Author Comment

by:Gina060497
Comment Utility
Thanks much for help.

Gina
0

Featured Post

Threat Intelligence Starter Resources

Integrating threat intelligence can be challenging, and not all companies are ready. These resources can help you build awareness and prepare for defense.

Join & Write a Comment

When writing generic code, using template meta-programming techniques, it is sometimes useful to know if a type is convertible to another type. A good example of when this might be is if you are writing diagnostic instrumentation for code to generat…
  Included as part of the C++ Standard Template Library (STL) is a collection of generic containers. Each of these containers serves a different purpose and has different pros and cons. It is often difficult to decide which container to use and …
The goal of the tutorial is to teach the user how to use functions in C++. The video will cover how to define functions, how to call functions and how to create functions prototypes. Microsoft Visual C++ 2010 Express will be used as a text editor an…
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.

744 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question

Need Help in Real-Time?

Connect with top rated Experts

18 Experts available now in Live!

Get 1:1 Help Now