C++/WinRT: CoreApplication::Run(IFrameworkViewSource const&) is throwing E_INVALIDARG - c++-winrt

I'm trying to figure out why at this point in the code I'm getting an E_INVALIDARG hresult:
// main.cpp
class App : public implements<App, IFrameworkView>
{
// stuff ...
};
class AppFactory : public implements<AppFactory, IFrameworkViewSource>
{
public:
IFrameworkView CreateView()
{
return make<App>();
}
};
int WINAPI wWinMain(
_In_ HINSTANCE,
_In_ HINSTANCE,
_In_ LPWSTR,
_In_ int)
{
init_apartment();
auto vpf = make<AppFactory>();
CoreApplication::Run(vpf); // <-- throwing E_INVALIDARG somewhere inside CoreApplication::Run
uninit_apartment();
return S_OK;
}
I'd have expected a compile error if I didn't do something required by a class inheriting implements<AppFractory, IFrameworkViewSource>, but as far as I know I'm checking (static) boxes.
fwiw the exception is triggered here:
// Windows.ApplicationModel.Core.h
template <typename D> auto consume_Windows_ApplicationModel_Core_ICoreApplication<D>::Run(winrt::Windows::ApplicationModel::Core::IFrameworkViewSource const& viewSource) const
{
check_hresult(WINRT_IMPL_SHIM(winrt::Windows::ApplicationModel::Core::ICoreApplication)->Run(*(void**)(&viewSource)));
}
The thing inside check_result(...) is what's returning E_INVALIDARG, and subsequently triggering the exception. I'm not a super expert at writing windows applications, largely still in the "copy the template and hope it works while trying to understand something" phase. If there's some kind of tool I should be using to understand what the actual argument I'm passing is that is invalid, I'd appreciate some kind of pointer. I would think if I'm not passing the correct thing here, the strong type check of the argument would trigger a compile error and I'd have an opportunity to address the issue.
Honestly I'm lost here, would appreciate a hint towards where to look to resolve my issue. Thank you.
Update:
Don't know if this is relevant but in the Output tab in VS a line prints out:
Exception thrown at 0x00007FFA6D9A4FD9 (KernelBase.dll) in MyProgram.exe: WinRT originate error - 0x80070057 : 'serverName'.
I have no idea what this is... "serverName"? I don't even see a mention of this in the CoreApplication::Run docs.

Related

How to resolve assert WINRT_ASSERT(!is_sta()) in winrt::impl::blocking_suspend

I have a Win32 DLL I am trying to convert to be usable from UWP. I need to replace file handling code (CreateFile, ReadFile, etc.) to the WinRT safe equivalents (Windows::Storage::StorageFile). I have the code converted and compiling, but when I run the app I get this exception calling get on the returned async operations and I am not sure how to resolve this.
Ok, took a bit to figure out what I was doing wrong but the correct way to handle this in my case is to wrap my code in a co_routine and then call it using PPL.
IAsyncOperation<int> DoWork()
{
co_await winrt::resume_background();
…
return someValue;
}
int Foo()
{
return create_task([]{
return DoWork().get();
}).get();
}

Excetpion handling in c++/cli

Actually i am working on c++/CLI dll which is using C# dll and c++/cli dll will use from native c.
c++/cli code is like:-
public ref class Class1
{
// TODO: Add your methods for this class here.
public:
static Managed_EMV_DLL::Managed_EMV ^obj = gcnew Managed_EMV(); // object of c# class
bool INIT_READER(unsigned int *);
bool READ_KEY(unsigned int *ERROR_CODE,unsigned char *RETURN_ARRAY, unsigned int *Array_LENGTH);
};
-i want to handle the exception in c++/CLI code,
-handle exception when c# dll not found.
how i can make it.
What is the exact problem you're facing .... See the below example format.
try
{
}
catch(FormatException ^) // display an appropriate message
{
Console::WriteLine(L"You must enter a valid number "
L"and no other character!");
}
Just sort out what exception could be thrown from C# dll and then put appropriate handles in your C++/CLI code.
I want to handle any kind of exception not only FormatException or TypeInitializationException.
Here i write code like:-
try
{
}
catch (Exception^ ex)
{
Console::WriteLine("Error in C++/CLI INIT function: {0}", ex->ToString());
}
catch (...)
{
Console::WriteLine("Error in INIT");
}
and it works good.... i hope it will catch any kind of exception...

MFC state invalid when DLL called through LoadLibrary

i'm fighting with MFC and dynamicly linking DLLs with LoadLibrary. It seems that I cannot get the MFC state right when the app calls DLL, and the DLL calls back in the same call. Ultimately, it leads to tons of asserts.
Here is code mock-up of what i'm doing.
The application is just normal, straight from the wizard MFC app. I've got button somewhere and this is the button's handler:
void callback()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
CDialog1 dlg;
dlg.DoModal();
}
typedef void (*TPluginMainFunc)(void*);
void CTheApp1View::OnTestRun1()
{
static HMODULE hPluginMFCShared = LoadLibrary( _T("PluginMFCShared") );
if ( hPluginMFCShared )
{
TPluginMainFunc func = (TPluginMainFunc) GetProcAddress( hPluginMFCShared, "plugin_main" );
if ( func )
{
func(callback);
}
}
}
Then the 'PluginMFCShared' looks like this:
typedef void (*TFunc)();
extern "C" void GS_EXTERNAL_ENTRY plugin_main(TFunc func)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
func();
CDialog1 dlg;
dlg.DoModal();
}
So, the idea is that the app (CTheApp1View::OnTestRun1) loads a library and calls a function directly passing in a callback pointer. The library would use that callback to execute something from the app before continuing.
I thought AFX_MANAGE_STATE will take care of the MFC state, but there seem to be something more that needs to be done.
A test project could be found at (make sure TheApp1 project is set to be the start-up project):
SystemOfPlugins.zip
Any ideas?
Thanks for any suggestions.
Here's another suggestion. In your App variable, add an AFX_MODULE_STATE* variable named m_pModuleState, and initialize it at the end of the InitInstance funciton,
m_pModuleState = AfxGetModuleState();
Modify your callback function to set the application state before opening the dialog, and then set back the original state before exiting the function
void callback()
{
//Get the original state
AFX_MODULE_STATE* pOriginalState = AfxGetModuleState();
//Set the mfc state
AfxSetModuleState(((CTheApp1App*)&theApp)->m_pModuleState);
//Do stuff here
CDialog1 dlg;
dlg.DoModal();
//Set the mfc state back to its original state
AfxSetModuleState(pOriginalState);
}
And keep your plugin as it was in your example
extern "C" void GS_EXTERNAL_ENTRY plugin_main(TFunc func)
{
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
func();
CDialog1 dlg;
dlg.DoModal();
}
This way, you would call AFX_MANAGE_STATE in your plugins, but when some of the plugin make a call to the callback function, you make sure to set the app's state so it can find the good dialog resources and execute state-specific functions
I looked at your code, and I got it working by modifiying 2 functions :
in pluginMFCShared.cpp, I called AFX_MANAGE_STATE after the call to func()
extern "C" void GS_EXTERNAL_ENTRY plugin_main(TFunc func)
{
func();
AFX_MANAGE_STATE(AfxGetStaticModuleState( ));
CDialog1 dlg;
dlg.DoModal();
}
In theapp1view.cpp, I removed the AFX_MANAGE_STATE
void callback()
{
CDialog1 dlg;
dlg.DoModal();
}
Now, the two dialogs pops one after another
Are you building the dll with the _LIB preprocessor flag? If so, check if you really should - the whole 'MFC dll' concept is antiquated, there is no reason to use it anymore. Then, forget about all the AFX_MANAGE_STATE stuff. In your dll, store the HMODULE of the dll that is passed to DllMain, and use ::AfxSetResourceHandle() to the correct value before each use of a CDialog or similar. Wrap it in a smart pointer-like class that sets the correct resource handle and resets it to the old one (= the main app's one, usually 0x4000...) when the object goes out of scope.
For all purposes where you can pass a resource handle directly (LoadString etc), you don't even have to touch the global handle.
Much easier to work, and much more transparent. The resource handle is the only one that is relevant for MFC state in MFC versions since VS6 anyway.

Managed C++, Object reference not set to an instance of an object

I've run into this problem before, but never in a situation like this. I'm completely confused. As the question states, I'm getting the runtime error "Object reference not set to an instance of an object." Using the debugger tools, I think I've pinpointed the problem to this line:
dataFileLocation = path;
The entire function is here:
void DATReader::SetPath(String^ path)
{
if(!File::Exists(path))
{
MessageBox::Show( "DATReader (missing dat file: \n"+path+"\n )", "Error", MessageBoxButtons::OK, MessageBoxIcon::Exclamation);
return;
}
dataFileLocation = path;
}
dataFileLocation is declared here, but nothing is assigned to it:
ref class DATReader
{
private:
System::String^ dataFileLocation;
// ...
}
Now I know the reason I'm getting the error is because dataFileLocation is assigned to nothing. But I'm having problems assigning it. When I add = 0; to it, it won't build because its a ref class. When I try to assigned it to = 0; in the constructor, it yells at me for trying to convert it from a System::String^ to an int. If I assign it to a = gcnew String(""); it builds, but throws the same runtime exception.
I don't get it, am I reading the debugger wrong, and this isn't the source of the problem at all? I've just started to use managed code recently, so I'm confused :\
You may want to check and make sure your DATReader object isn't null as well It may be throwing the exception at your DATReader.SetPath() call.
This is a nicety in C# that's missing in C++/CLI. C# generates code that ensures this can never be null. Easily seen in the debugger by setting a breakpoint on the method and inspecting "this". Here's an example program that reproduces the exception:
#include "stdafx.h"
using namespace System;
ref class Example {
String^ dataFileLocation;
public:
void SetPath(String^ path) {
dataFileLocation = path; // Set breakpoint here and inspect "this"
}
};
int main(array<System::String ^> ^args)
{
Example^ obj /* = gcnew Example */;
obj->SetPath("foo");
return 0;
}
Remove the /* */ comments to fix. Fix your code by looking at the call stack to find the method that forgot to instantiate the object.
Managed C++ uses nullptr for null references. So you can check:
if (path == nullptr) { ... }
or use:
if (!String::IsNullOrEmpty(path))

How do I map Windows System error codes to boost::error_condition?

In the code below I would like to replace Windows WinSock error WSAEINTR=10004 with a generic boost system error code, but how do I map the code I found in the debugger, with the generic enums?
timeout_.expires_from_now(posix_time::seconds(15));
timeout_.async_wait( boost::bind(&cancel_socket_fn,this,_1) );
asio::streambuf rd_buf;
unsigned length = read_until( socket_, rd_buf,delimiter_string, error );
timeout_.cancel();
if(error)
{
// how do I make this portable?
if(error.value()==WSAEINTR) throw request_timeout_exception()
else throw my_asio_exception(error,"Unable to read header");
}
...
cancel_socket_fn(system::error_code e) { socket_.cancel(); }
if (error == boost::asio::error::interrupted)...
And I think here is a design error because if this code is called from the thread where io_service::run() (or similar) is called then cancel_socket_fn() will not be called until read_until() finishes. Or if they are in different threads then here are synchronization problems because timer methods are not thread-safe.