Solved

How to use DLL again

Posted on 1997-06-13
10
358 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
ID: 1163916
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
ID: 1163917
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
ID: 1163918
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
Active Directory Webinar

We all know we need to protect and secure our privileges, but where to start? Join Experts Exchange and ManageEngine on Tuesday, April 11, 2017 10:00 AM PDT to learn how to track and secure privileged users in Active Directory.

 

Author Comment

by:Gina060497
ID: 1163919
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
ID: 1163920
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
 

Author Comment

by:Gina060497
ID: 1163921
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
ID: 1163922
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
ID: 1163923
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
ID: 1163924
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
ID: 1163925
Thanks much for help.

Gina
0

Featured Post

Active Directory Webinar

We all know we need to protect and secure our privileges, but where to start? Join Experts Exchange and ManageEngine on Tuesday, April 11, 2017 10:00 AM PDT to learn how to track and secure privileged users in Active Directory.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

Suggested Solutions

Introduction This article is a continuation of the C/C++ Visual Studio Express debugger series. Part 1 provided a quick start guide in using the debugger. Part 2 focused on additional topics in breakpoints. As your assignments become a little more …
Container Orchestration platforms empower organizations to scale their apps at an exceptional rate. This is the reason numerous innovation-driven companies are moving apps to an appropriated datacenter wide platform that empowers them to scale at a …
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 goal of the video will be to teach the user the difference and consequence of passing data by value vs passing data by reference in C++. An example of passing data by value as well as an example of passing data by reference will be be given. Bot…

830 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