# Help seriously needed with seemingly very simple problem (static instances, DLLs)

This topic is 4015 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Recommended Posts

Seriously, this problem is really, REALLY annoying me now. I thought it would take me a day to solve, but it's been holding me up for the past two weeks now, and as such I am mightily annoyed. Now, all I want to do, is to have a single instance of something, shared between DLLs. I've been making the problem simpler and simpler, and still can't get it to work. I'm now just trying to get an int to change its value when a DLL is loaded. Here's what I have:
//Main.h
#include "Test.h"
int main(){
std::cout &lt;&lt; i;
std::cout &lt;&lt; i;
}

// Test.h
__declspec(dllexport) int i;

// DLL.h
#include "Test.h"
extern "C" {
class proxy {
public:
proxy(){
i = 5;
}
};

proxy p;
}


Now, I've been told the reason this doesn't work is that a separate copy of i is being compiled into the app and the DLL, and that I should replace it with an accessor implemented in a source file, but this just gives me an unresolved external symbol linker error. Can someone please point out what I'm doing wrong, or even give me a little code that'll compile, so I can see what I'm supposed to be doing? I'm really tearing my hair out over this one, and I'm far too young to go bald. Please help! Thanks people!

##### Share on other sites
c dont have classes do they?

##### Share on other sites
So you have a value stored in your DLL, and you want your application access that value. The value cannot be accessed directly, but you have to provide functions to access that value. Your application might look like this:
// declare the function as being in a DLL__declspec(dllimport) int getValue();...int main(){  int value = getValue();  return 0;}

Now when compiling the DLL, instead of using "dllimport" you have to use "dllexport", so that the function (or even a class) is visible to the application.
__declspec(dllexport) int getValue();__declspec(dllexport) void setValue(int newValue);...int value;...int getValue(){  return value;}void setValue(int newValue){  value = newValue;}

There are also some examples.

##### Share on other sites
Thanks, that helps quite a lot. I was a bit unclear in my original post though, I actually meant I have some state in the app that I want DLLs to access. I've rearranged and fiddled with the code you posted, but I still can't get it working. It seems I'm just hopelessly inadequate when it comes to DLLs, which is a problem since they're the main focus of my current project...

If it's not too much trouble, would it be possible for somebody to post up a little bit of code that I can copy and paste into my IDE and compile, since everything I write is wrong :(

##### Share on other sites
So you want the DLL to read/write a variable of the application ? You can pass a function pointer to the DLL that points to a function that can read/write that variable, then the DLL can use that function pointer to access the variable indirectly.

The code then may look like this (untested):
// for the DLLextern "C" __declspec(dllexport) setFunctionPointers(  int (*getter)(), void (*setter)(int));// the function pointersint (*getValue)();void (*setValue)(int);setFunctionPointers(int (*getter)(), void (*setter)(int)){  getValue = getter;  setValue = setter;}void test(){  int i = getValue();  setValue(i + 3);}

and
// for the applicationextern "C" __declspec(dllimport) setFunctionPointers(  int (*getter)(), void (*setter)(int));int value;int getValue(){  return value;}void setValue(int newValue){  value = newValue;}int main(){  setFunctionPointers(getValue, setValue);  ...  return 0;}

Instead of passing around function pointers you may instead provide an implementation for some interface (i.e. in C++ a class with virtual functions), then pass a pointer to that object to the DLL.

##### Share on other sites
Well, I tried that code out (after fixing some tiny errors, and separating out into h/cpp files), and I get an unresolved external symbol error -

error LNK2019: unresolved external symbol __imp__setFunctionPointers referenced in function _main main.obj

I thought the __declspec(dllimport) told the compiler/linker that the function was to be found in a DLL?

Thanks for being so patient, I appreciate it a lot :)

##### Share on other sites
Check this example, explanation follows:
// dll.ccextern "C" {__declspec(dllexport) void setFunctionPointers(int (*getter)(), void (*setter)(int));__declspec(dllexport) void test();}// the function pointersint (*getValue)();void (*setValue)(int);void setFunctionPointers(int (*getter)(), void (*setter)(int)){  getValue = getter;  setValue = setter;}void test(){  int i = getValue();  setValue(i + 3);}

// main.cc#include <iostream>// for the applicationextern "C" {__declspec(dllimport) void setFunctionPointers(int (*getter)(), void (*setter)(int));__declspec(dllimport) void test();}int value;int getValue(){  return value;}void setValue(int newValue){  value = newValue;}int main(){  std::cout << "value = " << value << std::endl;  setFunctionPointers(getValue, setValue);  std::cout << "value = " << value << std::endl;  test();  std::cout << "value = " << value << std::endl;  return 0;}

Compile, link and run with:
(using MinGW)
gcc -c dll.ccgcc -shared -o dll.dll dll.odlltool -l dll.lib -a -D dll.dll -z dll.def dll.ogcc -c main.ccg++ -o main.exe main.o dll.lib

The DLL exports two functions setFunctionPointers() and test(), both having C linkage. (In the previous example the 'void' was missing, sorry.) The dll.cc is compiled with "gcc -c dll.cc" to an object file "dll.o", then linked to create the DLL with "gcc -shared -o dll.dll dll.o".

With the "dll.dll" itself, runtime linking can be performed by calling LoadLibrary(), then GetProcAddress(). But to make things easier and let the application automatically load all required DLLs a loadtime, an import library "dll.lib" may be created.

This import library contains wrappers for every function that the DLL exports to redirect the call to the DLL. It also contains code to load the library (i.e. calls LoadLibrary()) and to obtain the addresses of the exported functions (via GetProcAddress()). Creation of the import library is done by calling "dlltool -l dll.lib -a -D dll.dll -z dll.def dll.o". This also creates a text file "dll.def", which can be used to check the exported functions.

Compiling the application is done with "gcc -c main.cc", then linking the "main.o" and "dll.lib" to a "main.exe" is performed with "g++ -o main.exe main.o dll.lib". Calling g++ instead of gcc is necessary because a C++ library (iostream) was used and g++ automatically adds the required paths for that library when linking.

##### Share on other sites
Ah! It's all clicked into place! Thanks very much for that, it's working now, and I think I understand dynamic libraries too :) Thanks for all your help, I've rated you up.

##### Share on other sites

This topic is 4015 days old which is more than the 365 day threshold we allow for new replies. Please post a new topic.

## Create an account or sign in to comment

You need to be a member in order to leave a comment

## Create an account

Sign up for a new account in our community. It's easy!

Register a new account

• ### Forum Statistics

• Total Topics
628696
• Total Posts
2984267

• 19
• 9
• 13
• 13
• 11