1

I'm trying to compile some other people's wrapper program on a large system, in which it's using a global object from another file, the definition of the class is like:

class __declspec(dllexport) A
{
...
static A * instance;
}

And in my separate source file (which I want to build to a .exe), I included the header file A.h, and declare at the beginning like this

A * A::instance;

to access the data in A.

The problem is, this piece of code can be built successfully on Linux, now when I try to build it in windows NT, it will have issues.

  1. If I leave it like this, the compiler will complain with a C2491 error, definition of dllimport function not allowed.

  2. If I remove this line of A declaration, I'll get a lot of error LNK2001: unresolved external symbol.

Not quite sure what is the problem here, I did some research online, but couldn't find a good answer, I myself is not that familiar with dll import/export and some C++ tricks either. Can some one provide some insights on the problem or which direction should I spend my time on to figure this out?

Or say, if I already have a static object like this, and I want to write another program to access it, how exactly should I do?

Please also correct me if I made any mistakes here. Thanks!

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Derek
  • 1,085
  • 2
  • 20
  • 36
  • You can't use `class` in a C program - so your question is confusing us (if not yourself). I've worked out a fix to the wording that doesn't make a big mess. You might want to change the suffix of the '`.c`' file to the C++ suffix - but I'm not sure which suffix that is on Windows. On Unix, you'd use `.C` or `.cxx` or `.cpp` as the suffix. – Jonathan Leffler Nov 22 '11 at 23:26
  • Yah, thanks for the correction. But I'm a little bit confused now, to me it's just building a .exe from a .c or .C, and it's based on a C++ system, there are several similar .exe built like this already, and working fine on both linux and windows. Does the suffix really matter here? – Derek Nov 22 '11 at 23:31
  • Side note: You might want to know that singletons are considered an anti-pattern (see [wikipedia](http://en.wikipedia.org/wiki/Singleton_pattern)), so try avoiding it – Shahbaz Nov 22 '11 at 23:33
  • Dunno about on the machine, but you need to distinguish between C code and C++ code here on SO or people will jump on you like a tonne of bricks - much harder than I did. Originally, your title said 'separate C file', but the first thing you did was include a header that is not valid C code. Do not confuse the two languages; they are different. – Jonathan Leffler Nov 22 '11 at 23:34
  • I see, I guess I'm making a C program but have dependencies on a C++ system, is this the correct way of saying it? – Derek Nov 23 '11 at 01:25

4 Answers4

1

I think the keyword you need is extern, as in:

extern A *A::instance;

This says the variable A::instance is defined somewhere else, but you're telling the compiler about it so you can use it by name in this file.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
  • Yes, I forgot to mention in my post that I tried that, exactly what you suggested, but would get a error 'error C2720: 'A::instance' : 'extern ' storage-class specifier illegal on members' – Derek Nov 23 '11 at 00:10
0

__declspec(dllexport) is used when you want to export your function in a DLL. It should not be necessary as long as you're not calling the class from another DLL.

But I suspect your problem is related to using .c files and not the class specification. Try to read this by the way. It discusses dllexport in just-enough-detail Windows & C++: extern & __declspec(dllimport)

Community
  • 1
  • 1
Jan
  • 4,366
  • 6
  • 22
  • 21
0

Singleton usually has a function, like

A::instance = NULL;
A * get_instance() {if (!A::instance) A::instance = new A; return A::instance;}

If you have a function like this you don't have to access A::instance directly.

And sorry, but what are you doing? Including a C++ header in a C program? Does it even compiles?

Evan Dark
  • 1,311
  • 7
  • 7
0

Personally I usually hide the instance in the .cpp file in an anonymous namespace. Then I provide a getInstance() function that returns a pointer or reference to it and I dllExport that function.

If you want to enforce things you can make the constructors for A private and make getInstance a friend.

Michael Daum
  • 820
  • 6
  • 12