Hi - I've been at this for hours, so... say hello to my first post.

I'd like to allow my many cpp files to call on a function from DLL funcs I've brought in using LoadLibrary/GetProcAddress/etc, but, when I include the header file into the multiple cpp's, I get the "Already defined" compiler error. I'm kindof a noob, so I've been throwing #pragma once at the start of each and every file, and using the extern keyword prodigiously, but, I'm not sure how to handle this situation.

Here are samples of my code - hopefully it's enough to get your help.

func.h

//  Declaring the handles for the dll, and function pointers.  I initialize this 
//  in main.c  (in the hopes that I only define it once...  to no avail)

#pragma once
#ifndef LIB_SET
#define LIB_SET	1
	HINSTANCE dll_name;

	typedef int (CALLBACK* func1_pt)(int);
	func1_pt func1;
#endif
cpp1.cpp

//  Got a bunch of stuff going on in files like this one that include func.h in order 
//  to make use of its functions.  Even when I have just one of these files, I get
//  a compiler error.

#pragma once
#ifndef LIB_SET
#include "func.h"
#endif

void cpp1() {
  func1();
}
main.cpp

#pragma once
#ifndef LIB_SET
#include "func.h"
#endif
#include "cpp1.h"

	/*dll_name = LoadLibrary("dll_name.dll");
	func1 = (func1_pt)GetProcAddress(dll_name,"FUNC1");*/
cpp1();

When I try to compile the error msg reads similarly to: "cpp1.obj : error LNK2005: "void (__stdcall* func1)()" (?func1@@3P6XHH@ZA) already defined in main.obj"

Based on my Googling/Binging, I'm thinking that my typedef line counts as an allocation, which cannot be done twice, but then, I'm not sure how else I can call the dll functions, which themselves are workarounds for workarounds, but that's another story...

Any help would be much appreciated. Hopefully I've provided enough info.

Thanks,

SM

Of course, after 3 hours of searching and experimenting, I get it to compile 2 minutes after my post.

When I used the extern keyword on "func1_pt func1;" in func.h, and then redeclared it in main.cpp, everything compiled.

I guess I wasn't using the "extern" keyword THAT prodigiously... ( I should say that I had already tried using it, but, on the typedefs as opposed to the function declarations... Ah well.)

Some comments...
Do you understand now why you need the extern keyword?

Your use of include guards is a little over-the-top. Placing the #ifndef ... around #include statements normally results in faster compilation, but in my opinion it is way too messy if projects get bigger.
Generally, if you use a modern compiler and put '#pragma once' in the header file the compilation speed is already considerably faster compared to just #ifndef... in the .h file. So putting it also around #include ".." will probably not even give any noticeable advantage.

Also, if you created the DLL there are easier ways to link with it than on run-time. Especially if they're in the same solution in Visual Studio, but the exact answer kind of depends on which version you use, if any of course.

Honestly, I only think I understand what it's for... A variable needs to be declared in order to be called by cpp code, but can only be defined once. The extern keyword allows me to declare the variable, with the implication that it will be defined in some other location in my project.

I'm having a bit of trouble understanding why the compiler craps out, though, when I say "func1_pt func1;" twice -- after all, I'm saying the exact same thing... So finicky...

I don't normally use include guards. They're in there because the pragma keyword didn't seem to be helping with multiple definitions, so I threw it in there just to be sure. My first time importing functions from other DLLs, so, I thought maybe the declarations behave differently...

A simpler method to include the DLL would be nice. Does it matter that I didn't create it myself? All I have is the DLL with a bunch of html files describing function behaviour. I'm using Visual C++ 2008 Express.

As for an update, the functions I called in are only partially working... One of them is an object creator, which returns void, so, ok... The other one checks for existence of the object, and returns 1, correctly (which implies that the creator function worked). But the third, which I assume would return a value from the object, returns 0 all the time. Haven't been able to figure out why, yet.

Would it take a lot to assume that this DLL would be so easily compatible with Visual C++? My next step would be to simply ask the DLL's creator...

Thanks for the response!

This article has been dead for over six months. Start a new discussion instead.