|
I need to pass data between from a 32-bit to 16-bit process. I was thinking of using memory-map file. But someone told me that under 32-bit the memory-map file is private and the 16-bit process cannot read the location. Is this true? Is there other way to pass data beside using memory-map file?
|
|
|
|
|
Two methods come to mind, there may be more.
1) Use DDE (Dynamic data exchange). The DDEML library make this easier than using
the DDE functions directory. There are examples with MSVC 1.5 onwards and/or platform
SDK. MSVC 1.5 was 16 bit.
2) Use WM_COPYDATA and SendMessage().
This is defined for Win32 onwards, however there is nothing to prevent you using this
message (you may need to define it yourself for Win16) in your 16 bit programs.
I've done both of the above techniques in the past ('96/'97 ish) on both 16 and 32 bit
OSes.
Stephen Kellett
|
|
|
|
|
I am trying to use SetClassLongPtr() function but i get compilation error. MSDN says its available in winuser.h header but when I looked in my include directory for VC++, I couldn't find this function in winuser.h. I do have SetClassLong() in winuser.h file. I also installed SP5.
Any thoughts? Thank you,
Arpit Bhatt.
|
|
|
|
|
SetClassLongPtr() is the Win64-aware version of SetClassLong(). The former takes a LONG_PTR (long int, pointer-sized) whereas the latter takes a LONG (long int, always 32 bits). If you don't expect to be compiling or running on Win64 anytime soon, you can just use SetClassLong(). If you need to definition of SetClassLongPtr(), download the Platform SDK to get the latest header files.
--Mike--
http://home.inreach.com/mdunn/
All your base are belong to ME~!
|
|
|
|
|
Thanks for all the previous help, My App is in its final stage.
I have a reporting module in my app that generates a CTreeCtrl View of all the Work the User has done during their session, and is Serializeable as well.
When the User CLick on a Node of the tree I have a function that will output detailed information on the Action. INformation stored in Objects in an Obrray. My Problem is a simple One.
Where Can I put My output!!?
I can get the text and write the text but what I would like is an ajoined CEdit or Similar CWnd Derived object to output the text to.
How can I do this? WHat is the Best Method? I require it to be MultiLine as My output will look like this
Date: blaha alblka
Computer Name: ksdfjlkasjd
Action: COPY FILE
STEP 1: OPEN FILE :: SUCCESS!!
STEP 2: OPEN DEST :: SUCCESS!!
STEP 3: OPEN FILE :: SUCCESS!!
and so on.
Now Is there a way to use Set Window Text or similar function that will output a MultiLine String or a series of strings..
any help / suggestions would be appreciated.
thanks.
recurse.org - Recusion For the Rest Of Us.
|
|
|
|
|
A CEdit will show multiple lines if you output \n\r to denote a line end. In fact, you can do this in a static as well, even when you're using the dialog editor. Just type \n\r in your string and you'll get multiple lines. I guess you can therefore use CEdit or CStatic, it's up to you according to the appearance you want, plus the fact that a CEdit takes input ;0)
Christian
The content of this post is not necessarily the opinion of my yadda yadda yadda.
To understand recursion, we must first understand recursion.
|
|
|
|
|
for that kind of output i use a listbox or listctrl
---
"every year we invent better idiot proof systems and every year they invent better idiots"
|
|
|
|
|
I am using m_strCount as my DataExchange variable for a static text label (I also tried edit box). When I do:
m_strCount.Format( "%d", i );
I get a memory leak in my debug window:
Detected memory leaks!
Dumping objects ->
strcore.cpp(118) : {65} normal block at 0x007D1970, 45 bytes long.
Data: < 1143> 01 00 00 00 04 00 00 00 20 00 00 00 31 31 34 33
Object dump complete.
I am pretty new to MFC, so I am unsure what could cause this. I used the ClassWizard to create the variable association and i is merely an integer I used for counting.
Thanks.
|
|
|
|
|
That's a pretty weird one. Are you sure the leak is caused by that single line?
Can you post some more code?
BTW: What I've always learned to use is :
m_strCount.Format("%i", i);
G'luck.
--
Alex Marbus
www.marbus.net
But then again, I could be wrong.
|
|
|
|
|
Reall y - I didn't know %i worked, I've always used %d as per the examples in MSDN. ( I'm sure you're right, I'm just surprised the documentation didn't seem to mention it ).
Christian
The content of this post is not necessarily the opinion of my yadda yadda yadda.
To understand recursion, we must first understand recursion.
|
|
|
|
|
I will post more code when I have access to it, but I do know for sure that I remove all other code from the function and re-added it step-by-step until I found the issue. Originally I thought it was because I was using a DWORD dwCount with %d (then I switched it to %lu and it still did it) then I made a new integer (i) which did the same thing. Comment it out, and same sh*t. I will post my function tomorrow and I hope you might find an answer for me! I am not manually allocating anything, and by the core dump (strcore.cpp) it seems that the string is the only logical source of the problem. TRACEs on i don't dump either!
Thanks,
Christian
|
|
|
|
|
I'm kind of wondering what is being leaked - here's a trick that can sometimes find the culprit. It's more useful if the dump always shows the same allocation number.
Start your debug session with F10 - when it stops at the program entry, open the variables window and type in _crtBreakAlloc on a new line - you should get a -1 for the current value. Change that to the allocation number of the dump (1143) and the code will break when the allocation occurs. Use the call stack to see what object is being allocated.
This doesn't always work - the declspec of _crtBreakAlloc is controlled by the _CRTIMP macro in the runtime lib, meaning it's not always exported and visible to your application.
You can also search the MSDN for a more advanced approach to using _crtBreakAlloc.
|
|
|
|
|
Well, I created a new project, put a new Static Text control on my form, created a variable for it, copied code exactly from my old project and no more memory leaks.
I think it was because I changed the control I was using from an Edit Control to a Static Text, and used the same name. I checked to see if the DataExchange was set up correct and it seemed fine. Only thing I could think of would be behind-the-scenes type handling issues from changing the control type.
Thanks for the help though!
|
|
|
|
|
Hi,
I am using LoadLibrary() and GetProcAddress() to get an exported function from a dll. The exported function looks like this:
extern "C"
{
char *getStuff()
{
return new char[10];
}
}
When I call this function everything works fine until I try and 'delete' the memory that was allocated in this function. I get this error in the debug version - "HEAP[GenericTester.exe]: Invalid Address specified to RtlValidateHeap( 2f0000, 7b27a0 )". From what I guess that means that the application is trying to free memory from a different heap than the memory was allocated from?
My question then is: how do I allocate memory inside of the GetProcAddress() function that can be freed by the calling application?
Thanks!
|
|
|
|
|
|
well the hyperlink was supposed to take you to the article, but I tested it and it failed. I should have included the article title
DLL newing objects on process heap
Its on the next page down after the page this is on (with 20 odd to the page)
Stephen Kellett
|
|
|
|
|
Thanks!
It works now. I linked both with 'MultiThreaded DLL' so that the dll and application both use the same heap manager.
|
|
|
|
|
I usually go a different route in this case.
I generally add 2 functions: a CreateXXX and a DestroyXXX. The Create does the allocation and destroy frees the memory.
This has the following side benefit: usually you are not simply allocating a block of memory, you are setting up other things like access to ports, hw resources, etc. When it comes time to free the memory, you usually have to cleanup other stuff, so why not do it all in one spot and the end user doesn't have to worry about the details.
Mike
|
|
|
|
|
That is a good idea. I'm not sure that I want to use it in this case though?
The function in the DLL is called many times and returns many character buffers. That means that I have to keep track of all of these allocated character buffers in the dll, so that wehn DestroyXXX is called I free them all. I also can't have a DestroyLastAllocatedBuffer() function that frees the most recently allocated character buffer because the function in the DLL can be called by many different threads. (caveat: you probably could do both of the above with some extra work, but it might be more work than it is worth?)
I'd prefer for the calling application to be able to call the DLL function to get a characted buffer and then free it right after it is done with the buffer.
I think I have another solution though. You can create a C++ object with a destructor that does the memory freeing. It seems to work, anyone see any problems?
// Text holder class
CTextHolder
{
public:
CTextHolder()
~CTextHolder() { delete text; };
char *text;
};
// This is the exported function in the dll
extern "C"
{
CTextHolder * getText()
{
CTextHolder *blah = new CTextHolder();
blah->text = new char[20];
return blah;
}
}
// This is the function in the application that calls the exported function in the DLL
void testCall(void)
{
HMODULE mod = LoadLibrary("d:\\plugin.dll");
if(mod == NULL)
return;
// Test function is typdefed as.. typedef CTextHolder * (*aFunc)(void);
testFunction getText = (testFunction) GetProcAddress(mod, "getText");
if(getText == NULL)
return;
CTextHolder *blah = getText();
// Yay.. this seems to work fine
delete blah;
FreeLibrary(mod);
}
|
|
|
|
|
You wouldn't need to keep a list of anything.
s = CreateXXX();
...
DestroyXXX( s );
The functions would be something like this:
char *CreateXXX()
{
return new char[20];
}
///
//I would actually Code CreateXXX as follows
//ERRCODE CreateXXX( char **s )
//{
// *s = new char[20];
// return NOERR;
///}
ERRCODE DestroyXXX( char *s )
{
delete s[];
}
|
|
|
|
|
That seemed like a good solution to me too and I tried it, but it gave me an access violation. There may have been some bugs in my code (not allocating a large enough buffer and overflowing it), I'll try it again.
Thanks!
|
|
|
|
|
I think thats called a destructor.
|
|
|
|
|
I agree,
The CreateXXX,DestroyXXX approach is a good approach *if* the DLL the is designed to
be used as a black box, where it is always responsible for allocation and deallocation
of resources. However the original poster did not specify that.
Sometimes the black box approach is not appropriate for architectural or performance
reasons. Other times it is. I think both approaches have their merits.
Stephen Kellett
|
|
|
|
|
I am trying to use RasDial to establish an internet connection, but am getting an error that I don't understand. Here is the code that I am using:
RASDIALPARAMS dialParams;
DWORD dwRes;
CString cs;
char szError[50];
dialParams.dwSize = sizeof( RASDIALPARAMS );
strcpy( dialParams.szEntryName, "" );
strcpy( dialParams.szPhoneNumber, "szPhone" );
strcpy( dialParams.szCallbackNumber, "" );
strcpy( dialParams.szUserName, "szUser" );
strcpy( dialParams.szPassword, "szPW" );
strcpy( dialParams.szDomain, "" );
dwRes = RasDial( NULL, NULL, &dialParams, 0, NULL, &m_hRasConn );
if( dwRes == 0 )
{
     m_list.AddString( "Success." );
}
else
{
     RasGetErrorString( dwRes, szError, sizeof(szError) );
     cs.Format( "Error: #%d = %s - Handle: %s", dwRes, szError, (m_hRasConn == NULL) ? "NULL" : "Non-NULL" );
     m_list.AddString( cs );
}
The error that I'm getting is that it "Cannot find phonebook entry." My understanding is that this makes no sense, since in Win98, phonebooks are not valid and should be ignored.
I've checked the article at http://www.codeproject.com/internet/dialup.asp, but my code seems identical to that example.
Does anyone have any suggestions?
Thanks,
Matt J
|
|
|
|
|
Hello, the codegurus around the world.;)
I think that you should put any name in szEntryName.
If you put szEntryName as "", it means no entry phonebook.
Have a nice day!
-Masaaki Onishi-
|
|
|
|