I want to export global data in a DLL
-
I found these words in the MSDN: "Global variables in a DLL source code file are global to each process using the DLL." I know this to be true, because the following dll and app work for me: ----- stupidDll.h ----- #ifndef STUPIDDLL_H #define STUPIDDLL_H int __declspec(dllexport) getStupidInt(); #endif ------------------------- ----- stupidDll.cpp ----- #include "stupidDll.h" int x = 7; int getStupidInt() { return x; } ------------------------- ----- stupidApp.cpp ----- #include "stupidDll.h" #include "stdio.h int main() { printf("%d %d\n", getStupidInt()); return 0; } ------------------------- But say I don't want to have to call a function to get at the value of x. Shouldn't there be someway to export the symbol x in the DLL (just like I can export the symbol getStupidInt()) ? I.e., I want to be able to have something like: extern int x; in stupidDll.h so that applications can reference this global data directly. I presume I need some sort of __declspec on the above, but I haven't been able to figure it out yet. In case it matters, the data I want to export are a couple of C++ objects -- not simple ints. Thanks much, Matt Busche
-
I found these words in the MSDN: "Global variables in a DLL source code file are global to each process using the DLL." I know this to be true, because the following dll and app work for me: ----- stupidDll.h ----- #ifndef STUPIDDLL_H #define STUPIDDLL_H int __declspec(dllexport) getStupidInt(); #endif ------------------------- ----- stupidDll.cpp ----- #include "stupidDll.h" int x = 7; int getStupidInt() { return x; } ------------------------- ----- stupidApp.cpp ----- #include "stupidDll.h" #include "stdio.h int main() { printf("%d %d\n", getStupidInt()); return 0; } ------------------------- But say I don't want to have to call a function to get at the value of x. Shouldn't there be someway to export the symbol x in the DLL (just like I can export the symbol getStupidInt()) ? I.e., I want to be able to have something like: extern int x; in stupidDll.h so that applications can reference this global data directly. I presume I need some sort of __declspec on the above, but I haven't been able to figure it out yet. In case it matters, the data I want to export are a couple of C++ objects -- not simple ints. Thanks much, Matt Busche
Have you tried to put in your DLL header the following declaration?
extern __declspec(dllexport) int x;
and in the DLL code:int x;
PS. IMHO, global variables suck, especially in an OO design.
Le temps se perd, "Si" n'existe pas Tous les remords n'y changeront rien Le temps se perd, "Si" n'existe pas Donc à présent le choix reste mien
-
I found these words in the MSDN: "Global variables in a DLL source code file are global to each process using the DLL." I know this to be true, because the following dll and app work for me: ----- stupidDll.h ----- #ifndef STUPIDDLL_H #define STUPIDDLL_H int __declspec(dllexport) getStupidInt(); #endif ------------------------- ----- stupidDll.cpp ----- #include "stupidDll.h" int x = 7; int getStupidInt() { return x; } ------------------------- ----- stupidApp.cpp ----- #include "stupidDll.h" #include "stdio.h int main() { printf("%d %d\n", getStupidInt()); return 0; } ------------------------- But say I don't want to have to call a function to get at the value of x. Shouldn't there be someway to export the symbol x in the DLL (just like I can export the symbol getStupidInt()) ? I.e., I want to be able to have something like: extern int x; in stupidDll.h so that applications can reference this global data directly. I presume I need some sort of __declspec on the above, but I haven't been able to figure it out yet. In case it matters, the data I want to export are a couple of C++ objects -- not simple ints. Thanks much, Matt Busche
use a def file, it's better for C exports. Don't try it, just do it! ;-)
-
Have you tried to put in your DLL header the following declaration?
extern __declspec(dllexport) int x;
and in the DLL code:int x;
PS. IMHO, global variables suck, especially in an OO design.
Le temps se perd, "Si" n'existe pas Tous les remords n'y changeront rien Le temps se perd, "Si" n'existe pas Donc à présent le choix reste mien
KaЯl, Yes. Actually that was the first thing I tried. I get: stupidApp.obj : error LNK2001: unresolved external symbol "int x" (?x@@3HA) stupidAp/stupidApp.exe : fatal error LNK1120: 1 unresolved externals Error executing link.exe. And yes, in general I agree global variables (or in my case objects) suck, but if you knew what I was doing, I suspect you might forgive me. But I am not going to defend myself here. Never-the-less I appreciate your response and would be interested in any other ideas you may have. Thanks, Matt
-
use a def file, it's better for C exports. Don't try it, just do it! ;-)
Alexander, As I said in my email, I am trying to export two C++ objects -- not a simple integer. Do you still recommend a defs file? In addition, I have a few C++ base-class declarations and a few global C++ functions that I am also exporting. I would expect putting these in a defs file would not be as straight forward. Can you mix a defs file for data with __declspec for classes and functions all within the same DLL? Thanks much, Matt P.S., what is the significance of the superscript M. in your login?
-
KaЯl, Yes. Actually that was the first thing I tried. I get: stupidApp.obj : error LNK2001: unresolved external symbol "int x" (?x@@3HA) stupidAp/stupidApp.exe : fatal error LNK1120: 1 unresolved externals Error executing link.exe. And yes, in general I agree global variables (or in my case objects) suck, but if you knew what I was doing, I suspect you might forgive me. But I am not going to defend myself here. Never-the-less I appreciate your response and would be interested in any other ideas you may have. Thanks, Matt
Hum...The method I indicated works well for me. Perhaps is there a mix between C and C++ decorations. I've sent you a small sample, hope this help. K.
Le temps se perd, "Si" n'existe pas Tous les remords n'y changeront rien Le temps se perd, "Si" n'existe pas Donc à présent le choix reste mien
-
Hum...The method I indicated works well for me. Perhaps is there a mix between C and C++ decorations. I've sent you a small sample, hope this help. K.
Le temps se perd, "Si" n'existe pas Tous les remords n'y changeront rien Le temps se perd, "Si" n'existe pas Donc à présent le choix reste mien
KaЯl, Thanks very much for your sample code! I've got it working now. You never mentioned anything about dllimport! That was my problem. From my experimentation, I now believe the following:
- For global data (certainly for built-in data types and I presume this goes for global C++ objects as well), the DLL source code module must declare the data using __declspec(dllexport), BUT the application module must declare the data using __declspec(dllimport). This seems a tad annoying since the header file must look different for the DLL compile and the Application compile.
- For functions (and I presume this goes for class declarations as well), the DLL source code must likewise declare the function using __declspec(dllexport), BUT IN CONTRAST TO THE CASE FOR DATA the application can declare the function using __declspec(dllimport), __declspec(dllexport), or nothing at all!
Actually I just found the dllimport/dllexport descriptions in the MSDN that would seem to support my claims, though I find it somewhat cryptic -- the kind of description that makes sense only after you already know what it's trying to describe. Maybe I'm just mentally slow or lazy. I will have to read the entire section a time or two to see what I can learn. Anyway, here is what I did for my source code to get this to work. ----- stupidDll.h ----- #ifndef STUPIDDLL_H #define STUPIDDLL_H #ifndef DllDecl #define DllDecl __declspec(dllimport) #endif int DllDecl getStupidInt(); extern DllDecl int x; #endif ------------------------- ----- stupidDll.cpp ----- #define DllDecl __declspec(dllexport) #include "stupidDll.h" int x = 8; int foo = 7; int getStupidInt() { return foo; } ------------------------- ----- stupidApp.cpp ----- #include "stupidDll.h" #include "stdio.h" int main(){ printf("%d %d\n", getStupidInt(), x); return 0; } ------------------------- As you can see, my DllDecl macro normally expands to __declspec(dllimport); however, I predefined the DllDecl macro in StupidDll.cpp before the #include "StupidDll.h" to force it to instead expand to __declspec(dllexport). Thanks again for your help. It was most helpful. Matt
-
KaЯl, Thanks very much for your sample code! I've got it working now. You never mentioned anything about dllimport! That was my problem. From my experimentation, I now believe the following:
- For global data (certainly for built-in data types and I presume this goes for global C++ objects as well), the DLL source code module must declare the data using __declspec(dllexport), BUT the application module must declare the data using __declspec(dllimport). This seems a tad annoying since the header file must look different for the DLL compile and the Application compile.
- For functions (and I presume this goes for class declarations as well), the DLL source code must likewise declare the function using __declspec(dllexport), BUT IN CONTRAST TO THE CASE FOR DATA the application can declare the function using __declspec(dllimport), __declspec(dllexport), or nothing at all!
Actually I just found the dllimport/dllexport descriptions in the MSDN that would seem to support my claims, though I find it somewhat cryptic -- the kind of description that makes sense only after you already know what it's trying to describe. Maybe I'm just mentally slow or lazy. I will have to read the entire section a time or two to see what I can learn. Anyway, here is what I did for my source code to get this to work. ----- stupidDll.h ----- #ifndef STUPIDDLL_H #define STUPIDDLL_H #ifndef DllDecl #define DllDecl __declspec(dllimport) #endif int DllDecl getStupidInt(); extern DllDecl int x; #endif ------------------------- ----- stupidDll.cpp ----- #define DllDecl __declspec(dllexport) #include "stupidDll.h" int x = 8; int foo = 7; int getStupidInt() { return foo; } ------------------------- ----- stupidApp.cpp ----- #include "stupidDll.h" #include "stdio.h" int main(){ printf("%d %d\n", getStupidInt(), x); return 0; } ------------------------- As you can see, my DllDecl macro normally expands to __declspec(dllimport); however, I predefined the DllDecl macro in StupidDll.cpp before the #include "StupidDll.h" to force it to instead expand to __declspec(dllexport). Thanks again for your help. It was most helpful. Matt
Matthew Busche wrote: You never mentioned anything about dllimport you asked how to export ;) You guessed well. Generally, the technique is the following: use one header file for both your DLL and your application. In it, define something like
#if _MY_DLL #define MYDDL_WHATEVER _declspec(dllexport) #else #define MYDDL_WHATEVER _declspec(dllimport)
Then, in the header, use:extern MYDDL_WHATEVER int x;
In the settings of the DLL project, define the preprocessor definition MYDDL_WHATEVER. Et hop, it's done :) You could also take a look to this article[^], it may contain useful info. Matthew Busche wrote: Thanks again for your help. It was most helpful. My pleasure, and welcome on Codeproject! :-D K.
Le temps se perd, "Si" n'existe pas Tous les remords n'y changeront rien Le temps se perd, "Si" n'existe pas Donc à présent le choix reste mien