|
Hi again,
I am using data_segs to share an LPSTR variable but the sharing only seems to work with multiple instances of the same EXE - literally. When I retrieve the value of the var from another app, a different EXE, I get the default value of the variable originally initialized in the module.
Code in DLL:
#pragma data_seg("Shared")
__declspec(dllexport) LPSTR lpsCommandParameter = NULL;
#pragma data_seg()
#pragma comment(linker,"/SECTION:Shared,S")
extern "C"
{
__declspec(dllexport) VOID SetCommandParameter(LPSTR lpsParam);
__declspec(dllexport) LPSTR GetCommandParameter();
}
VOID SetCommandParameter(LPSTR lpsParam)
{
lpsCommandParameter = lpsParam;
}
LPSTR GetCommandParameter()
{
return lpsCommandParameter;
}
Code in Form1.cpp (Form1.exe) - Button1_Click - This button sets the value of lpsCommandParameter to "Hello"
typedef VOID (*pSetCommandParameter)(char *lpsParam);
HINSTANCE DllHandle = LoadLibraryW(L"my.dll");
if (DllHandle == NULL)
{
ShowMessage("NULL");
return;
}
pSetCommandParameter pSetParam = (pSetCommandParameter)GetProcAddress(DllHandle, "SetCommandParameter");
if (pSetParam == NULL)
{
ShowMessage("pSetParam is NULL");
return;
}
pSetParam("Hello");
Code in Form1.cpp (Form1.exe) - Button2_Click - This one retrieves the value of lpsCommandParameter:
typedef char *( *pGetCommandParameter )();
HINSTANCE DllHandle = LoadLibraryW(L"my.dll");
if (DllHandle == NULL)
{
ShowMessage("NULL");
return;
}
pGetCommandParameter pGetParam = (pGetCommandParameter)GetProcAddress(DllHandle, "GetCommandParameter");
if (pGetParam == NULL)
{
ShowMessage("pGetParam is NULL");
return;
}
ShowMessage(pGetParam());
Now the sharing works fine as long as multiple instances of that same Form1.exe are instantiated. Put the Button2 code in a second application, say Form2.exe and click the button to retrieve the value of lpsCommandParameter and you'll get a blank. I instantiated 4 instances of Form1.exe and the value of lpsCommandParameter from the DLL is returned fine but I keep getting blanks from a different EXE. I want this data to be visible among different EXEs as my project depends on shared data and I don't want to write anything on disk so I really want do this via data sharing in DLLs.
|
|
|
|
|
I think I might have found out what's going on. The above code works fine with an integer. According to MSDN:
Each process gets its own address space. It is very important that pointers are never stored in a variable contained in a shared data segment. A pointer might be perfectly valid in one application but not in another.
And when you think of it, LPSTR is an array of chars which *is* a pointer. I've tried the above example also with a char * (before I read this) and still made no difference as well as a std:string. All I want to really share is a bunch of chars.
Update: I found more clarification here: http://sites.google.com/site/jozsefbekes/Home/windows-programming/shared-data-segment-in-a-dll[^]
You can only have fixed size data here (no dynamic arrays or CString)
You have to initialize all data otherwise it won't be shared (Of course it makes no sense to put pointers here as the address would be valid in one process only)
So to share a string, you can create a char[] array and initialize it and then just store the value in it.
modified 7-Jan-12 16:54pm.
|
|
|
|
|
Hey everyone,
I am having difficulties in setting values to global variables in a DLL module. I am using (learning) Visual C++ 2010 Express. I am not exactly sure what I am doing wrong as this works fine with BCB. I have some DLL code written in BCB that I want ported to VC++.
In DLL source code I have this:
__declspec(dllexport) int MyInt = 100;
extern "C"
{
__declspec(dllexport) void SetMyInt(int NewValue)
{
MyInt = NewValue;
}
__declspec(dllexport) int GetMyInt()
{
return MyInt;
}
}
In main file:
Button 1 click:
typedef void (*pSetMyInt)(int Value);
HINSTANCE DllHandle = LoadLibraryW(L"file.dll");
if (DllHandle == NULL)
{
ShowMessage("Handle is NULL");
return;
}
pSetMyInt pSetInt = (pSetMyInt)GetProcAddress(DllHandle, "SetMyInt");
if (pSetInt == NULL)
{
ShowMessage("pSetInt is NULL");
return;
}
pSetInt(89);
FreeLibrary(DllHandle);
Button 2 Click:
typedef int (*pGetMyInt)();
HINSTANCE DllHandle = LoadLibraryW(L"file.dll");
if (DllHandle == NULL)
{
ShowMessage("NULL");
return;
}
pGetMyInt pGetInt = (pGetMyInt)GetProcAddress(DllHandle, "GetMyInt");
if (pGetInt == NULL)
{
ShowMessage("pGetInt is NULL");
return;
}
int Value = pGetInt();
FreeLibrary(DllHandle);
No matter what I do, the internal variable in the DLL module never gets set. It remains to the default value initialized on the top of my DLL file. This is so simple, how can it not work? I must be doing something wrong.
|
|
|
|
|
It is working as expected.
Here is what that is happening.
When button 1 is clicked, the DLL is loaded into memory and the value of MyInt which is 100 is loaded into memory.
After that the value of MyInt is changed in memory to 89 .
Then when FreeLibrary is called, the DLL and all memory used by it (including MyInt ) is unloaded from memory.
At this point, the value 89 that you set is lost.
Now when button 2 is clicked, the DLL is freshly loaded into memory along with the value 100 that belongs to MyInt .
So when you read the value of MyInt , it is 100 as expected.
To get what you're trying to do here are the steps -
Call LoadLibrary and GetProcAddress in some initialization routine before the button click event handlers are invoked.
In the button 1 click routine simply call SetMyInt .
In the button 2 click routine simply call GetMyInt .
You can call FreeLibrary in a separate cleanup routine that must be invoked only at the end.
|
|
|
|
|
Oh yes...Of course...Thank you! Yes, it makes perfect sense. It works as expected and yes commenting that line out does work and I will indeed create a separate routine that cleans up an array of handles. What was I thinking? I feel so embarrassed.
|
|
|
|
|
Hey friend, I want to ask, how to make setup from project VC6, like package and deployment wizard in VB. because I want use my project in the other PC without instal VC6. Thank you...
|
|
|
|
|
|
okay, i will try your suggest... thank you...
|
|
|
|
|
|
okay, i will try your suggest... thank you...
|
|
|
|
|
|
Which IDE you use for development on Linux platforms?
1. Does it support driver development or kernel development?
2. Does it provide a nice GUI for application development, for example - can you drag and drop controls from toolbars to forms?
3. Is debugging of threads, memory location and registers possible in that ?
I am an MFC developer and now want to try my hands on Linux.
|
|
|
|
|
I always used Eclipse[^] and found it suited my needs in both Java and C++.
Unrequited desire is character building. OriginalGriff
I'm sitting here giving you a standing ovation - Len Goodman
|
|
|
|
|
Hmm i was also thinking for the same. Earlier I had used eclipse for Java applications however Netbeans was also good.
|
|
|
|
|
I don't use an IDE for Linux development. vim+ctags+gdb combination is what works for me.
|
|
|
|
|
Same here.. I've occasionally used Eclipse, but I find the control afforded by understanding the underlying tools is worth its weight in gold.
vim/ctags/gdb all the way. We also use basic make files for all our making needs.
|
|
|
|
|
If you are coming from windows, be aware that the mechanisms on Linux regarding shared libraries are very different than Windows. By default globals in a DLL's namespace are not resolved to the same instance as they are in the caller's program for Windows.. On Linux if you have a global called 'g_xxx' in both your main program and your shared object (.so), they will be resolved to ONE instance of the variable that is global across your main program and your .so. That can come as quite a shock if you aren't expecting it.
If you are following proper O-O techniques, this will most likely not be an issue.. but if you are dealing with real-world code written by folks who aren't so disciplined, this may be an issue for you.
There are many small 'gotchas' between Windows and Linux, but this one IMO is the big one.
|
|
|
|
|
vi
Why is common sense not common?
Never argue with an idiot. They will drag you down to their level where they are an expert.
Sometimes it takes a lot of work to be lazy
Individuality is fine, as long as we do it together - F. Burns
|
|
|
|
|
Like I *EDIT* my code for windows.
Starting to think people post kid pics in their profiles because that was the last time they were cute - Jeremy.
|
|
|
|
|
Hi all,
can anybody help me to join multiple excel file in single file using excel automation
thanks in advance.
|
|
|
|
|
I'd simply open the two documents in concern, copy the information as required. Depends on just how you want to combine the two files.. For instance - do you wish to combine the information in Sheet1 of each workbook into a single Sheet1 of a third workbook? Do you wish to add an entire worksheet from each input workbook such that the output contains as many sheets as there are input files?
My first step would be to start excel and begin recording a macro. I would then do manually what I'd like to do with automation before I stopped the macro recording and looked at the code that my copy/paste actions had created.
I'm assuming that you want to control excel using msvc? Got no idea about the necessary COM work involved, there's plenty of examples around here. You could also use your c++ code to start an instance of excel with a macro enabled workbook that would perform all of your desired work. (if you'd prefer to use some quick'n'dirty VBA)
|
|
|
|
|
You might have better luck in the Visual Basic forum, as this sounds like a job for VBA.
|
|
|
|
|
Le@rner wrote: can anybody help me to... Ok, so what do you have so far?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|
|
I am sure some of you gurus will jump up when you see this question.
Not to worry - I am just looking for a easy way to clear <b>MY registry entries </b>during debugging.
I am using WriteProfileString and associated API functions and since I am adding multiple entries into registry during development I would like to be able to clear them programmatically ( I hate this word – sounds so stuffy ) .
I am not particularly willing to use another API set, so how can I accomplish this ?
Thanks for reading
Vaclav
|
|
|
|
|
Vaclav_Sal wrote: I am using WriteProfileString and associated API functions and...I would like to be able to clear them programmatically...
So why can't you use WriteProfileString() to do this?
"One man's wage rise is another man's price increase." - Harold Wilson
"Fireproof doesn't mean the fire will never come. It means when the fire comes that you will be able to withstand it." - Michael Simmons
"Show me a community that obeys the Ten Commandments and I'll show you a less crowded prison system." - Anonymous
|
|
|
|