extern "C" int __declspec(dllexport)

Post date: Apr 29, 2011 7:34:36 AM

When providing an interface between modules that are built using two different vendor's compilers, it is important to ensure that the modules use common calling- and naming- conventions. This document discusses interface techniques for mixing modules created with Microsoft Visual C++ and modules created with Power++ or Watcom C/C++.

To provide an interface between Visual C++ and Power++ or Watcom C/C++, you will need to export and import functions and/or variables. Function definitions and prototypes should include the extern "C" directive and the __stdcall keyword. The former forces C linkage (i.e., turns off C++ name mangling); the latter ensures the standard Win32 calling convention is used. Variable definitions and declarations should also include the extern "C" directive.

If you want to write an Power++ or Watcom C/C++ EXE that calls functions or accesses variables exported from a Visual C++ DLL, then you must use the Visual C++ lib command to create an import library for the DLL. This import library can then be added to your Power++ or Watcom IDE project. The import library can also be used with the Watcom C/C++ wlink command if you are using command-line tools.

Calling Exported Functions

For each exported function in the DLL that is to be called from the EXE, do the following:

In the DLL source, define the function as:

extern "C" type __declspec(dllexport) __stdcall name( parameters )

{

...

}

In the EXE source, declare (prototype) the function as:

extern "C" type __declspec(dllimport) __stdcall name( parameters );

Accessing Exported Variables

For each exported variable in the DLL that is to be accessed from the EXE, do the following:

In the DLL source, define the variable as:

extern "C" { type __declspec(dllexport) name; }

Note: The braces ({}) are required. If you omit them, this becomes a declaration, not a definition.

In the EXE source, declare the variable as:

extern "C" type __declspec(dllimport) name;

Example

The following sample illustrates this technique:

msdll.cpp:

#include

extern "C" { int __declspec(dllexport) var1 = 10; }

extern "C" int __declspec(dllexport) __stdcall func1( int i )

{

printf( "func1(): var1 = %d\n", var1 );

printf( "func1(): i = %d\n", i );

return i * 2 + var1;

}

watexe.cpp:

#include

extern "C" int __declspec(dllimport) var1;

extern "C" int __declspec(dllimport) __stdcall func1( int i );

void main(void)

{

printf( "main(): var1 = %d\n", var1++ );

printf( "main(): func1 = %d\n", func1( 5 ) );

}

If you are building the EXE with Power++, select Files from the View menu to open the Files view window. Then in the Files view window, select Add File... from the File menu to add the import library to the Power++ project.

If you are building the EXE with Watcom C/C++ and you are using the Watcom IDE, click on the Target window for the Target that uses the DLL. Then, select New Source... from the Source menu to add the import library to the Watcom IDE project.

To build this sample using command line tools, follow these steps:

1. Compile and link the DLL:

cl /c msdll.cpp

link /dll msdll.obj

2. Create an import library for the DLL:

lib /NAME:msdll.dll /OUT:msdll.lib

3. Compile and link the EXE using the import library generated in step 2:

wpp386 watexe.cpp

wlink sys nt n watexe f watexe l msdll

Note: If you want to use the __cdecl calling convention instead of __stdcall, simply replace all occurances of __stdcall in the above sample with __cdecl.

For more details, visit http://www.sybase.com/detail?id=44623