My C++ code, which is part of Media Foundation Transform tend to able to run in Windows Store App (Metro)
I modify the C++ GrayscaleTransform
to include the following code.
However, my C++ code fails to locate namespace Windows::Storage
.
LPCWSTR zPath = Windows::Storage::ApplicationData::Current->TemporaryFolder->Path->Data();
Is there any additional settings I need to do?
I can make it compiled, by turning on Consume Windows Runtime Extension.
But by doing this, it will give me additional linking error and warnings.
warning LNK4197: export 'DllGetActivationFactory' specified multiple times; using first specification
warning LNK4197: export 'DllCanUnloadNow' specified multiple times; using first specification
warning LNK4197: export 'DllGetActivationFactory' specified multiple times; using first specification
warning LNK4197: export 'DllCanUnloadNow' specified multiple times; using first specification
error LNK2005: _DllCanUnloadNow@0 already defined in dllmain.obj
error LNK1169: one or more multiply defined symbols found
Comment out DllCanUnloadNow
will produce runtime error.
I get a runtime break at
// GrayscaleTransform.dll!Microsoft::WRL::Details::ModuleBase::ModuleBase() Line 155 + 0x46 bytes C++
ModuleBase() throw()
{
#ifdef _DEBUG
// This indicates that there were two instances of the module created or race conditon during module creation
// If you are creating object with new/delete please make sure that you haven't created more than one module
// and you disabled static initalization with __WRL_DISABLE_STATIC_INITIALIZE__
// otherwise please initialize/create module in main()
__WRL_ASSERT__(::InterlockedCompareExchangePointer(reinterpret_cast<void* volatile*>(&module_), this, nullptr) == nullptr &&
"The module was already instantiated");
SRWLOCK initSRWLOCK = SRWLOCK_INIT;
__WRL_ASSERT__(reinterpret_cast<SRWLOCK*>(&moduleLock_)->Ptr == initSRWLOCK.Ptr && "Different value for moduleLock_ than SRWLOCK_INIT");
(initSRWLOCK);
#else
module_ = this;
#endif
}
The linker errors occur because you enabled C++/CX in the GrayscaleTransform project. Your project defines the listed entry points in dllmain.cpp. When you enable C++/CX, vccorlib gets linked into your module, and it also defines these entry points.
The runtime error occurs because the C++/CX infrastructure in vccorlib creates a Module, and your entry point tries to create a different kind of Module. There can only be one Module in a module.
You need to make a few more changes to the GrayscaleTransform project to be able to use C++/CX in it:
Remove the four Dll*() functions from dllmain.cpp. You will rely instead on the definitions linked in from vccorlib. Note that the class registration (
ActivatableClass(CGrayscale)
) is still required.In the C++ Preprocessor options, ensure that
_WINRT_DLL
is defined in the "Preprocessor Definitions."In the Linker input options, remove the "Module Definition File."
Note that you will need to be very careful when mixing C++/CX and "low-level" C++ using WRL. Most expressions that involve C++/CX types can throw exceptions, and you must ensure that no exceptions are ever allowed to cross the ABI boundary.
Alternatively, consider not using C++/CX and instead using WRL throughout your project. It will be more verbose, but if you are already using WRL for other parts of the project, it may make more sense.