PRB: Linker error LNK2001 when calling 'C' functions from an XLL+ function

Reference: Q0018

Article last modified on 25-May-2005


The information in this article applies to:

  • XLL+ for Visual Studio 6 - 3, 4.1, 4.2, 4.3.1
  • XLL+ for Visual Studio .NET - 3, 4.1, 4.2, 4.3.1

Linker error LNK2001 when calling 'C' functions from an XLL+ function

Issue

I have a library function written in pure 'C'. When I try to call it from an XLL+ add-in function, I get linker error LNK2001: unresolved external symbol.

Solution

C++ allows more than one method to have the same name. Such functions are different from each other only with respect to their argument types and return type. Therefore, in order to tell them apart, C++ "decorates" the names with details of the argument types, and passes the decorated name to the linker, which can then select the correct function to be linked to.

You can stop the C++ compiler from decorating a function name by applying the C++ construct extern "C". For example, if you have a 'C' function declaration in your C++ code, as follows:

int MyFn(double x, double* y);
You can prevent the compiler from decorating the name by changing the declaration as follows:
extern "C" int MyFn(double x, double* y);

If your 'C' functions are declared in a header file, and the header file is used by code written in 'C" and in C++, then you need to be a little more careful. If your header file looks as follows:

int MyFn(double x, double* y);
int MyOtherFn(double x, double y, double* z);
The you should add extern "C" statements but you should also ensure that they are visible only from C++ code, as follows:
#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

int MyFn(double x, double* y);
int MyOtherFn(double x, double y, double* z);

#ifdef __cplusplus
} /* extern "C" */
#endif /* __cplusplus */

The 'C' compiler will ignore the extern "C" { statement and its matching closing brace. The C++ compiler will always see the statements, because __cplusplus is always defined in MS C++ code.