|
One possible solution is to simply add a call to get() or another C++ I/O function that waits for the user to press ENTER before terminating.
Lookup ShellExecuteEx() at MSDN.
Kuphryn
|
|
|
|
|
A Visual Basic Application accessed a C++ DLL. That DLL must allocate a block of memory and populate it. It should then pass the pointer to the first elements back to VB for outputing the results.
Q: How can I free the memory from the VB once I am done? Is using functions such a GlobalFree or HeapFree the solutions? Are there any caveats, problems?
Currently I have space allocated in VB, the pointer is passed to C++, and then space deallocated in VB. The problem here is that I do not know beforehand the exact size of the array, and the "to be on the safe side" allocation is quite wasteful.
Please help.
Thank you
|
|
|
|
|
I guess the proper question here is what is Visual C++'s new operator equivalent to : GlobalAlloc, HeapAlloc, LocalAlloc, CoTaskMemAlloc, etc?
If I know that, then I can probably use the appropriate method to free memory in VB.
|
|
|
|
|
Why can't you write a function in the DLL that does the deletion?
My neighbours think I am crazy - but they don't know that I have a trampoline. All they see my head bobbing up and down over the fence every five seconds
|
|
|
|
|
Because I need to output results in VB from this array before I deallocate it.
|
|
|
|
|
JWood's suggestion still applies. You have one function in the C++ DLL that allocates the memory, and another function in that DLL that deallocates the same memory. After the memory has been allocated, but before it is deallocated, the VB code can use it.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
This is actually an interesting point. I haven't thought about doing this before. I guess the question then becomes: does calling the DLL twice create more overhead than allocating excess amount of memory in VB?
|
|
|
|
|
"Calling a DLL" is actually a misnomer. The overhead comes in loading the DLL into the address space of the process. Once that happens, a function call is a function call.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
Like the others, the new operator allocates memory, but it's the only one that, when operating on objects, calls their constructor. Trying to mix memory-management routines has no positive results.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
What if I need to allocate a pure byte array, and I can take care of reading the data using CopyMemory in the appropriate format? Would that make a difference?
I guess new operator is compiler specific, but I found no reference to what it actually does. Other functions have different twists to it: you can zero the elements, you can move memory, etc. My theory is that if one of them does exactly what new in C++ compiler does, then things should be good.
Am I mistaken?
|
|
|
|
|
Anton A. Loukine wrote:
I guess new operator is compiler specific, but I found no reference to what it actually does.
Like this?
The most important thing is to not mix "allocate" and "deallocate" routines. In other words, new cannot be used with free() , and malloc() cannot be used with delete .
Both the DLL and EXE have their own list(s) of allocated memory blocks. If the DLL allocates a block of memory, for the creation of a new instance of a class, this memory is marked in the allocation list of the DLL. If the EXE tries to free this memory, the run-time library looks through its list of allocated memory blocks and fails (usually with a GP fault). Thus, even if the memory between the DLL and the EXE is completely shared, the logic for managing allocation breaks if two modules mix their allocation schemes.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
This is clear. However, if I exit the DLL, go back to VB, and then come back to the DLL with the pointer created in the first round, will that list of allocated memory blocks still be there? Also, you said that the DLL is loaded into memory when it's called.
Let's say we have a VB function:
{
....
call DLL
.....
call same DLL
....
}
is it going to load the DLL and unload it twice or once?
Thank you very much
|
|
|
|
|
Anton A. Loukine wrote:
However, if I exit the DLL,
Not sure what you mean by "exit the DLL" as it is either implicitly or explicitly linked. DLLs remain in the address space of the process, with all of their memory blocks intact, until the process explicitly unloads the DLL or the process itself goes away.
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
I actually tried to implement your suggestion, but they do not seem to work with my code:
In C++, I have:
short _stdcall QrgAlloc( double* dArray )
{
dArray = new double[ 2 ];
dArray[ 0 ] = 2.34;
dArray[ 1 ] = 2.55;
return 1;
}
short _stdcall QrgFree( double* dArray )
{
delete [] dArray;
return 1;
}
In VB, I have:
Dim l As Long
Dim d As Double
Dim nReturn As Integer
nReturn = QrgAlloc(l)
CopyMemory d, l, 4
MsgBox (d)
CopyMemory d, l + 4, 4
MsgBox (d)
nReturn = QrgFree(l)
That outputs wrong values and then crashes when freeing memory. Any thoughts?
Thanks
|
|
|
|
|
"double" is 8 bytes long in C...
"...Ability to type is not enough to become a Programmer. Unless you type in VB. But then again you have to type really fast..."
Me
|
|
|
|
|
Thanks Igor.
I picked up on that typo later on, too; however, the major issue remains: why does it crash when I supply the memory address to C++ dll for the second time for deallocation. Is the double* pointer a value of a "Long" type (4 bytes)?. If it is, then it doesn't really make sense why it's not working. Unless the memory addresses are wiped out by the time the DLL function exists.
|
|
|
|
|
>> then it doesn't really make sense why it's not working. <<
I agree, it doesn't make sence...
>> Unless the memory addresses are wiped out by the time the DLL function exists. <<
No, the memory addresses are not wiped out, because you are managing to access values from your VB code (I assume). What is wiped out is Runtime heap allocation info (like MCB blocks and etc). That can only be explained by DLL unloading after each call. I'm not GURU in DLL calls from VB, but it would be interesting to see how you declare those exported C functions in VB (Alias or etc).
What I recommend is to check the lifespan of your DLL, because your DLL code is available to you: put MessageBox or Debug breakpoints in DllMain or InitInstance/ExitInstance in DLL_PROCESS_ATTACH/DETACH and see when DLL loads/freed. That may give you some answers.
Also, you may set breakpoints/MessageBoxs in QrgAlloc( double* dArray ) and QrgFree( double* dArray ) and see if dArray you received in QrgFree is the same as dArray you return from QrgAlloc...
Alternatively, you may consider the following sequence in what you are doing:
imlement your VB/C code in the following manner:
1. Change QrgAlloc( double* dArray ), so it will be able to accept NULL argument as dArray --> in that case, should just return length of next allocation;
2. Allocate array in your VB code equal to the value of QrgAlloc returned on step 1;
3. Call now QrgAlloc( double* dArray ) with dArray equal to VB array allocated on step 2...
So, you don't have to allocate/free anything in C...
Regards
"...Ability to type is not enough to become a Programmer. Unless you type in VB. But then again you have to type really fast..."
Me
|
|
|
|
|
BTW: If you find out that VB unloads your DLL after each function call -- you can use the following trick to keep your DLL running.
Put extra LoadLibray as in here:
static HINSATNCE hInst = NULL;<br />
short _stdcall QrgAlloc( double* dArray )<br />
{<br />
if(!hInst)<br />
hInst = LoadLibrary("YourDllNameHere.dll");<br />
...
}<br />
short _stdcall QrgFree( double* dArray )<br />
{<br />
if(hInst)<br />
{<br />
FreeLibrary(hInst);<br />
hInst = NULL;<br />
}<br />
...
}
Not as beautiful, but may resolve the problem...
"...Ability to type is not enough to become a Programmer. Unless you type in VB. But then again you have to type really fast..."
Me
|
|
|
|
|
I've just realized that you basically have a BUG in your code.
If you are using default VB calling conventions then you are passing refference to l from VB to QrgAlloc => therefore your QrgAlloc function should be declared and implemented like that:
short _stdcall QrgAlloc( long* l)<br />
{<br />
double* dArray = new double[ 2 ];<br />
dArray[ 0 ] = 2.34;<br />
dArray[ 1 ] = 2.55;<br />
*l = (long)dArray;<br />
return 1;<br />
}
"...Ability to type is not enough to become a Programmer. Unless you type in VB. But then again you have to type really fast..."
Me
|
|
|
|
|
Experiment and find out. From memory, I think VB loads and unloads DLLs every time you call a function.
To be honest, once we start getting into context I would recommend writing a COM component. Using COM components is easier from VB6 anyway.
|
|
|
|
|
Hi!
How I can get the docking location (right, left, top or bottom) of a control bar?
|
|
|
|
|
how does one hide a folder from other people?
http://www.codeproject.com/tools/FolderHide.asp[^] says it makes the folder act like a shortcut to system folders (like Recycle Bin, Control Panel, etc.), but sadly, the tool came without source code.
|
|
|
|
|
You could try and notify the article's author. Others have made posts about it, so hopefully the source code will appear shortly. I suspect the article will be deleted otherwise (at least that's the impression that I got from Chris).
Otherwise, you may just have to use SetFileAttributes() .
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|
|
Hi,
I am sorry that I am asking a question not relevant to this section of MessageBoard, but I hope that somebody can help me out.
I use the WriteFile function in my MFC application to write data to a File from a Buffer.
When I see open the file, I see strange characters, while my data in the Buffer contains only numbers.
What can be the problem?
Thanks in Advance,
Deepak Samuel
|
|
|
|
|
A code snippet showing how you are writing to the file would be nice. How are you viewing the file once it's been written to?
Five birds are sitting on a fence.
Three of them decide to fly off.
How many are left?
|
|
|
|