AfxGetApp() pointer getting destroyed - visual-c++

I am using ATL dll.
I have a CWinApp derived object. In its initInstance(), when I call AfxGetApp(), it works fine and gives me the pointer of CWinApp. But after some more function calls, when I call AfxGetApp()/AfxGetAppName() etc,in a different function, then it is returning NULL.I guess that the CWinApp object is getting destroyed or something. With that thought, I put a breakpoint in ExitInstance but the code is not reaching there either. Could anyone help me out as to why this is happening and how can make it return the previous valid value.
Thanks

Make sure your DLL/EXE projects link to the same MFC library. I.e. Multibyte/unicode character set...

Related

Different Java objects having the same address, IsSameObject not working, and related global ref management problems

I've been banging my head on this problem for a week, and now I'm starting to understand what's going on, but no idea why, or how to fix it.
Let me describe what I'm doing. I have an assortment of various objects in Java, and I have a native library. Java objects inform the library of their existence by calling NativeLibrary.AddObject(this). The native library has a container of jobjects where I store global references to the Java objects, obtained with env->NewGlobalRef(object). The native library uses these stored references to access the Java objects, and it does work fine.
And here's the crucial part that does NOT work. Obviously, I want to be able to delete Java objects, not only add them. So, when a Java object is no longer needed, it calls NativeLibrary.RemoveObject(this). The native library implements it by iterating the list of stored objects (which are all global references, as you may remember) and finding a match with env->IsSameObject(passedObject, storedObjectGlobalReference).
And here's where the problem is: it doesn't work as expected, the Java objects are not matched to their global references properly. When I started digging and logging all the calls with all the parameters, I noticed a weird thing: the jobject parameter of the native call (which is this of Java objects) has the same value for different objects! Moreover, this value changes between the ``NativeLibrary.AddObject(this)andNativeLibrary.RemoveObject(this)` calls for the same object!
So, what's going on, and how can I store, keep track of and delete the references to Java objects in native code? To reiterate: everything works fine as long as I only create and store global refs; the correct objects receive notifications via these refs, no problem. But as soon as I try deleting these references via env->DeleteGlobalRef, I find out that in the NativeLibrary.RemoveObject(this) implementation fails to match the stored reference to the passed jobject.
I was with the same problem. The root cause was that the added item NativeLibrary.AddObject(this) not was the same object when I called NativeLibrary.RemoveObject(this). I was using junit and this was causing the problem, because junit create multiples objects to run each test. I found the problem using System.out.println with the object in Java side. Before add function System.out.println("add object: " + sameObject); and before remove function System.out.println("remove object: " + sameObject);. Sorry for poor english, I hope this help someone.

Passing managed reference (this) to unmanaged code and call managed callback

this is the source of the issue. My answer there was deleted with the hint to start a new question. So, here we go:
I want to pass the managed reference of this to unmanaged code. And then call the managed callback out of the unmanaged callback.
public ref class CReader
with a private field
private:
[...]
void *m_pTag;
[...]
In the constructor of the managed class I initialize the m_pTag like this:
m_pTag = new gcroot<CReader ^>(this);
Later, I pass this void *m_pTag to the unmanaged code. If the unmanaged callback is called, I'm casting the void *m_pTag back to managed reference and call the managed callback
(*(gcroot<CReader ^>*)pTag)->MANAGEDCALLBACKFUNCTION
and there is an exception thrown, if the DLL is used under another AppDomain. The Debugger stops in gcroot.h on line
// don't return T& here because & to gc pointer not yet implemented
// (T should be a pointer anyway).
T operator->() const {
// gcroot is typesafe, so use static_cast
return static_cast<T>(__VOIDPTR_TO_GCHANDLE(_handle).Target);
}
with Cannot pass a GCHandle across AppDomains.
My question is, what should I do?
Sincerly,
Sebastian
==================== EDIT ====================
I am now able to reproduce the problem. I've took some screenshots, to show the issue.
1st screenshot: constructor
snd screenshot: callback
The problem is, that the value-member of the struct gcroot in the callback is empty.
Thank you.
Sebastian
==================== EDIT ====================
Push.
The gcroot<> C++ class is a wrapper that uses the GCHandle class. The constructor calls GCHandle.ToIntPtr() to turn the handle into an opaque pointer, one that you can safely store as a member of an unmanaged struct or C++ class.
The cast then, later, converts that raw pointer back to the handle with the GCHandle.FromIntPtr() method. The GCHandle.Target property gives you the managed object reference back.
GCHandle.FromIntPtr() can indeed fail, the generic exception message is "Cannot pass a GCHandle across AppDomains". This message only fingers the common reason that this fails, it assumes that GCHandle is used in safe code and simply used incorrectly.
The message does not cover the most common reason that this fails in unsafe code. Code that invariably dies with undiagnosable exceptions due to heap corruption. In other words, the gcroot<> member of the C++ class or struct getting overwritten with an arbitrary value. Which of course dooms GCHandle.FromIntPtr(), the CLR can no longer find the handle back from a junk pointer value.
You diagnose this bug the way you diagnose any heap corruption problem. You first make sure that you get a good repro so you can trip the exception reliably. And you set a data breakpoint on the gcroot member. The debugger automatically breaks when the member is written inappropriately, the call stack gives you good idea why this happened.

The specified object is not recognized as a fake object. Issue

I am having an issue where a FakeItEasy call in an extremely simple test is failing with the error "The specified object is not recognized as a fake object." The call is simple:
A.CallTo(myService.MyMethod(listOfStringsFilter)).MustHaveHappened();
The fake is similarly simple (A.Fake()), and fakes out an interfance with one method, that takes in a list and returns a list. In debug mode, I see the instance of myService is of type {Fake IMyInterface}. Anyway, this issue is really holding me up, thanks in advance for your help.
Update:
This was my own darn mistake, I needed to make the call say:
A.CallTo(() => myService.MyMethod(listOfStringsFilter)).MustHaveHappened();
This was my own darn mistake, I needed to make the call say:
A.CallTo(() => myService.MyMethod(listOfStringsFilter)).MustHaveHappened();

Starting a method in another thread C++

I'm having trouble finding out how to run a method in a seperate thread in C++ (using Visual C++ 2008), I've tried a number of ways to do this but none of them so far have been successful.
I'm very new to C++ but a fairly experienced programmer in Java, but have been given a task to fix some bugs in an old C++ application. The program uses an object called 'Mpeg' to control packetising and depackitising an Mpeg file. After setting up an Mpeg object properly, mpeg.Depacketise needs to be called, which then runs the method DepacketiseInputFile().
I've tried to make DepacketiseInputFile() run in a seperate thread by both using _beginthread and the System::Threading::Thread object using
Thread^ th = gcnew Thread(gcnew ThreadStart(DepacketiseInputFile));
however this returns the errors
using &Mpeg::Depacketise gives the error
when using _beginthread the code I tried was
However with this I constantly had trouble getting the arguments correct, with errors like
cropping up.
Is there any simple way to do this that anyone can reccomend? I've spent a few days playing around with this but seem to be getting nowhere :(
Any help would be greatly appreciated.
Cheers.
What kind of type is Mpeg? What kind of method is DepacketiseInputFile?
If it's a regular unmanaged, C++ class, then use _beginthread, but you have to make DepacketiseInputFile a static. It cannot take a member function.
Also, don't call DepacketiseInputFile with DepacketiseInputFile(), pass it in with
&Mpeg::DepacketiseInputFile
You should use the void* you get to pass it to pass in a pointer to the Mpeg object (and then cast it back).
If you want to use ThreadStart, then Mpeg needs to be a managed class.
EDIT: If you want to make DepacketiseInputFile, but it needs to access the object, then you use the void* argument to pass in a pointer.
So in the .h:
void DepacketiseInputFileMember();
static void DepacketiseInputFile(void *thisObj);
Your code goes in DepacketiseInputFileMember(), and write DepacketiseInputFile like this:
void Mpeg::DepacketiseInputFile(void *thisObj)
{
Mpeg* mpeg = reinterpret_cast<Mpeg*>(thisObj);
mpeg->DepacketiseInputFileMember();
}
When you call _beginthread, use this
_beginnthread(&Mpeg::DepacketiseInputFile, (unsigned)0, anMpegObjectPointer);
where anMpegObjectPointer is a pointer to an object of type Mpeg. You have to make sure the lifetime of the object is longer than it would be needed in the thread.
Forgive my syntax, I am writing this in a textarea, not Visual Studio
Change
_beginthread(DepacketiseInputFile(), (unsigned)0, (void *)NULL);
to
_beginthread(DepacketiseInputFile, (unsigned)0, (void *)NULL);
You wanna pass the address of the function to run (DepacketiseInputFile) and not its return value of that function (which is what you get from DepacketiseInputFile()).
I'm assuming DepacketiseInputFile is declared as void DepacketiseInputFile(void*), and is not a non-static member function of some class. Otherwise, the types won't match even when you do remove the brackets.

Using CoWaitForMultipleHandles

Continuing from
Pausing execution of a Thread WITHOUT sleeping?
How do I use the CoWaitForMultipleHandles routine, as Lars Truijens suggested? I found the routine in the SyncObjs unit, however I get "undeclared identifier" when trying to call it? The IDE Insight does not bring anything up either? And yes, I have added SyncObjs to my Uses clause.
I can't see what other info I need to include - however feel more than free to ask for more info!
You can't call this function from SyncObjs, because it hasn't been declared in interface section. But TEvent.WaitFor actually calls CoWaitForMultipleHandles. Did you try it?
And please note its constructor declaration:
{ Specify UseCOMWait to ensure that when blocked waiting for the object
any STA COM calls back into this thread can be made. }
constructor Create(UseCOMWait: Boolean = False);

Resources