How to initialize an instance of IVectorView for C++/WRL? - c++

I'm trying to call get_Skus() method of IStoreProduct to retrieve its Skus property using C++/WRL (not C++/CX) and I can't find any suitable code examples. That method is defined as such (as I get it from the header file in Visual Studio):
virtual /* [propget] */ HRESULT STDMETHODCALLTYPE get_Skus(
/* [out][retval] */ __RPC__deref_out_opt IVectorView<ABI::Windows::Services::Store::StoreSku*> **value) = 0;
So when I try to do:
#include <Windows.Services.Store.h>
#include <wrl.h>
using namespace ABI::Windows::Services::Store;
using namespace ABI::Windows::Foundation::Collections;
IVectorView<StoreSku*> pStrSkus;
//IStoreProduct* pStorePrdct = ...;
if (SUCCEEDED(pStorePrdct->get_Skus(&pStrSkus)))
{
}
it gives me an error that:
'ABI::Windows::Foundation::Collections::IVectorView'
: cannot instantiate abstract class
I'm relatively new to WRL. Can someone show me how am I supposed to call that method?

You forgot a star - it should have been this:
IVectorView<StoreSku*>* pStrSkus;
if (SUCCEEDED(pStorePrdct->get_Skus(&pStrSkus)))
{
...
pStrSkus->Release();
}
Even better, use a ComPtr instead, so you don't have to release it manually:
ComPtr<IVectorView<StoreSku*>> pStrSkus;
if (SUCCEEDED(pStorePrdct->get_Skus(&pStrSkus)))
{
...
}

Related

Linker issue with DirectShow base class in mingw 64 bit

After porting a project from visual studio to mingw. I am getting the following linker error
undefined reference to `g_Templates'
undefined reference to `g_cTemplates'
The code which it points to looks something like this
#include <tchar.h>
#endif // DEBUG
#include <strsafe.h>
#include <combase.h>
extern CFactoryTemplate g_Templates[];
extern int g_cTemplates;
HINSTANCE g_hInst;
DWORD g_amPlatform; // VER_PLATFORM_WIN32_WINDOWS etc... (from GetVersionEx)
OSVERSIONINFO g_osInfo;
//
// an instance of this is created by the DLLGetClassObject entrypoint
// it uses the CFactoryTemplate object it is given to support the
// IClassFactory interface
class CClassFactory : public IClassFactory, public CBaseObject
{
private:
const CFactoryTemplate *const m_pTemplate;
...
public:
CClassFactory(const CFactoryTemplate *);
// IUnknown
STDMETHODIMP QueryInterface(REFIID riid, __deref_out void ** ppv);
STDMETHODIMP_(ULONG)AddRef();
STDMETHODIMP_(ULONG)Release();
// IClassFactory
STDMETHODIMP CreateInstance(LPUNKNOWN pUnkOuter, REFIID riid, __deref_out void **pv);
STDMETHODIMP LockServer(BOOL fLock);
// allow DLLGetClassObject to know about global server lock status
static BOOL IsLocked() {
return (m_cLocked > 0);
};
};
// --- COM entrypoints -----------------------------------------
//
// Call any initialization routines
//
void DllInitClasses(BOOL bLoading)
{
// traverse the array of templates calling the init routine
// if they have one
for (i = 0; i < g_cTemplates; i++) //<---------Cannot recognize this symbol
{
const CFactoryTemplate * pT = &g_Templates[i];
if (pT->m_lpfnInit != NULL)
{
(*pT->m_lpfnInit)(bLoading, pT->m_ClsID);
}
}
}
....
....
I have been searching on this issue for a while and have not made any progress. It seems that that this symbol exists in strmbasd.lib (debug version) and is generated from DirectShow base classes. I generated strmbasd.lib using mingw64 however I am still getting this linker error. I wanted to know if there was any other approach I could try .
I have used Direct Show for Microsoft Visual C++. And found no such issue. Microsoft SDK provides the libraries and headers as well as the base classes. You may want to check the link. I haven't used MingW, so I don't know about the issue of MingW. You may try it in MSVC, MSDN provides some handful informations and references for Direct Show. Please check the previous link mentioned above.
Your including dllentry.cpp/dllsetup.cpp from DirectShow BaseClasses assumes that you develop a filter library and you are expected to define template symbols in your code (example) to satisfy linker.
If you don't see how your code is referencing factories, you can define fake array and g_cTemplates of zero to pass through, however eventually there is something that makes linker drag these symbols into output.

Problems creating a unmanaged regular MFC DLL and call it from an managed C++ .NET app

I have a few questions about DLL's. I tried a lot but I can not get the complete picture. Most examples are in C# etc.
With the wizard in VS2005 I created a unmanaged MFC regular DLL (must be MFC because of remaining code). Then I tried to import it in a VS2005 managed .NET C++ application. See code below.
mfc_main.h:
//---------------------------------------------------------
// mfc_main.h : main header file for the mfc_main DLL
//---------------------------------------------------------
#pragma once
#ifndef __AFXWIN_H__
#error "include 'stdafx.h' before including this file for PCH"
#endif
#include "resource.h" // main symbols
class __declspec(dllexport) Cmfc_mainApp : public CWinApp
{
public:
Cmfc_mainApp();
// Overrides
public:
virtual BOOL InitInstance();
int SayHello(int j);
int init;
DECLARE_MESSAGE_MAP()
};
mfc_main.cpp:
//----------------------------------------------------------------
// mfc_main.cpp : Defines the initialization routines for the DLL.
//----------------------------------------------------------------
#include "stdafx.h"
#include "mfc_main.h"
#ifdef _DEBUG
#define new DEBUG_NEW
#endif
BEGIN_MESSAGE_MAP(Cmfc_mainApp, CWinApp)
END_MESSAGE_MAP()
Cmfc_mainApp::Cmfc_mainApp()
{
}
Cmfc_mainApp theApp;
BOOL Cmfc_mainApp::InitInstance()
{
CWinApp::InitInstance();
return TRUE;
}
int Cmfc_mainApp::SayHello(int j)
{
init = 12; // Comment this out the application works !!!!
return j * 6;
};
in application
[DllImport("mfc_main.dll",
EntryPoint = "?SayHello#Cmfc_mainApp##QAEHH#Z",
ExactSpelling = true)]
static int SayHello(int a);
......
private: System::Void button_Click(System::Object^ sender, System::EventArgs^ e)
{
int retval = SayHello(2);
}
My questions are:
1 - Why is it working without the init = 12 in the function SayHello and with the application crashes (error: Attempted to read or write protected memory)?
2 - Is in this case the InitInstance() executed although I don't call it (and why is there no ExitInstance)?
3 - Why do I see some examples giving the EntryPoint when using DLLImport and some don't?
4 - Can I give a delegate as parameter to a function in a MFC C++ DLL instead of a normal function pointer, to create a callback?
Methods cannot be P/Invoked. If you want to export a class from unmanaged DLL to be used in managed world, you have to flatten it, eg.
Create a constructor function, which looks like:
__declspec(dllexport) void * __stdcall MyClass_Create()
{
return new MyClass();
}
Create a destructor function, which looks like:
__declspec(dllexport) void * __stdcall MyClass_Destroy(MyClass * instance)
{
delete instance;
}
Flatten method calls. Let's suppose, that you have the following method in your class:
int MyClass::MyMethod(int i, double j) { ... }
Then you have to create a following function:
__declspec(dllexport) int __stdcall MyClass_MyMethod(MyClass * instance, int i, double j)
{
return instance->MyMethod(i, j);
}
Prepare P/Invoked external methods in C# (You already know how to do it, so I'll omit these)
Create instance of your class:
IntPtr instance = MyClass_Create();
Then call its method:
int i = MyClass_MyMethod(instance, 4, 2.0);
Finally, destroy the class:
MyClass_Destroy(instance);
Don't forget to add some error checking - I omitted it to keep the example clear.

Using a dll in C++ code

I want to use pjsipDll.dll in a c++ code. I got this dll from one of the sites, I only know how to build the code to obtain the dll file. So I did that and now I've the pjsipDll.dll file with me. I want to use certain functions in the DLL in my code(C++)
I tried the following code. << I haven't made/added any dll or .h file to the project, there is only the following CPP file>>
#include <iostream>
using namespace std;
int CallMyDLL(void)
{
/* get handle to dll */
HINSTANCE hGetProcIDDLL = LoadLibrary("G:\\July\\9.0\\pjsipdll\\Lib\\pjsipDll.dll");
/* get pointer to the function in the dll*/
FARPROC lpfnGetProcessID = GetProcAddress(HMODULE (hGetProcIDDLL),"dll_makeCall");
/*
Define the Function in the DLL for reuse. This is just prototyping the dll's function.
A mock of it. Use "stdcall" for maximum compatibility.
*/
typedef int (__stdcall * pICFUNC)(int, char *);
pICFUNC MyFunction;
MyFunction = pICFUNC(lpfnGetProcessID);
/* The actual call to the function contained in the dll */
int intMyReturnVal = MyFunction(5,"hello");
/* Release the Dll */
FreeLibrary(hGetProcIDDLL);
/* The return val from the dll */
returnintMyReturnVal;
}
void main()
{
cout<<"Hello World";
CallMyDLL();
getchar();
}
I learnt this way from some site, to use the function from a DLL.
The problem is, I get an ERROR:
error C2065: 'HINSTANCE' : undeclared identifier g:\july\9.0\pjproject-0.9.0\myproject\importerprojet\importerprojet\mycpp.cpp 9 importerProjet
Can anyone help me out with this. Or atleast point me to the post if this query is already addressed.
Thanks for your help,
Vinu.
You need to #include <windows.h>

C++ compiler won't recognize a member function and a type

Today it's the day of strange things....
Got a stupid hpp file and another stupid cpp file trying to implement a stupid class.
Here they are:
// HPP
#ifndef _WFQUEUE_MANAGER_PROXY_HPP_
#define _WFQUEUE_MANAGER_PROXY_HPP_
#include <iostream>
#include <string>
#include "workflow.hpp"
#include "wfqueue.hpp"
//-----------------------------------------------------------------------------
// Enum, struct, aliases
namespace middleware {
typedef struct {
std::string proxy_ipaddr; /* IP address to manager */
std::string proxy_port; /* Port to manager */
} WFProxyConfig;
}
//-----------------------------------------------------------------------------
// Class definitions
namespace middleware {
/*!
* This class provides network interface to access the workflow queue. It is
* important to notice that constructor is private in order to let a factory
* perform such a work.
*/
class WFQueueManagerProxy : public WFQueue {
/*!
* To let factory build properly this object, we provide access to every
* part of it.
*/
friend class WFQueueProxyFactory;
private:
/*!
* Privately constructs the object. Default configuration with loopback
* address and invalid port.
*/
WFQueueManagerProxy();
public:
/*!
* Destructor
*/
~WFQueueManagerProxy();
/*!
* Enqueues a workflow.
*/
void enqueue(const Workflow& workflow);
/*!
* Dequeues a workflow.
*/
const Workflow& dequeue();
private:
/*!
* Privately constructs the object. Assigning configuration.
*/
void ConfigureProxy(WFProxyConfig conf);
/*!
* Parameters for proxy.
*/
WFProxyConfig _config;
}; /* WFQueueManagerProxy */
} /* middleware */
#endif
Here the other
// CPP
#include "wfqueue_manager_proxy.hpp"
using namespace middleware;
//-----------------------------------------------------------------------------
// Constructors and destructor
/* Private constructor */
WFQueueManagerProxy::WFQueueManagerProxy() {
(this->_config).proxy_ipaddr = "127.0.0.1";
(this->_config).proxy_port = "0";
}
/* Destructor */
WFQueueManagerProxy::~WFQueueManagerProxy() {
}
//-----------------------------------------------------------------------------
// Public members
/* Enqueue */
void WFQueueManagerProxy::enqueue(const Workflow& workflow) {
}
/* Dequeue */
const Workflow& WFQueueManagerProxy::dequeue() {
}
//-----------------------------------------------------------------------------
// Private members
void WFQueueManagerProxy::ConfigureProxy(WFProxyConfig conf) {
}
Somebody please explain me why g++ tells me this:
wfqueue_manager_proxy.cpp: In
constructor
‘middleware::WFQueueManagerProxy::WFQueueManagerProxy()’:
wfqueue_manager_proxy.cpp:32: error:
‘class
middleware::WFQueueManagerProxy’ has
no member named ‘_config’
wfqueue_manager_proxy.cpp:33: error:
‘class
middleware::WFQueueManagerProxy’ has
no member named ‘_config’
wfqueue_manager_proxy.cpp: At global
scope: wfqueue_manager_proxy.cpp:51:
error: variable or field
‘ConfigureProxy’ declared void
wfqueue_manager_proxy.cpp:51: error:
‘WFProxyConfig’ was not declared in
this scope
ABSURD...
It does not recognize that typedef and doesn't recognize a private member too... and, more than everything... why does not g++ recognize a member function trying to see it as a variable?????????
I have tried everything...
PS (to who saw my earlier post): my virtual machine now is not the cause. I checked and got confirm that no virtual hard disk is corrupted or in collision with other virtual mem units.
Just a guess. Shouldn't it be
WFQueueManagerProxy::WFQueueManagerProxy() {
(this->_config).proxy_ipaddr = "127.0.0.1";
(this->_config).proxy_port = "0";
}
I get the error you are getting when I remove the declaration of WFProxyConfig (or change the name declared). Are you sure you posted the exact code that is producing the error?
Identifiers with leading underscores are reserved (include guards as well as _config). I'd be a little surprised if one of these is your problem - but not that surprised.
_config might even be a g++ extension keyword.
OK, this was the error....
I also compiled headers.. many gch were so created.... g++ didn't update those precompiled headers and got an old code... that's why it was indifferent to any change I did... sorry for disturb you guys... thanks a lot for your help

Error: the global scope has no GetUrl

I have a new problem with my C++ DLL... I have tried exporting the entire class instead of only one method. But the program doesn't want to compile now because of that the global scope has no GetUrl
Here is my "UrlConnector.h":
#define ConnectMe __declspec( dllexport )
namespace ConnectHttps
{
class ConnectMe
{
void GetUrl(char *url, unsigned int bufferLength);
};
}
and here is the part of my UrlConnector.cpp that isn't compiling:
#include "UrlConnector.h"
#include "MyConnectionClass.h"
#include
using namespace std;
namespace ConnectHttps
{
void ConnectMe::GetUrl(char* url, unsigned bufferLength)
{
MyConnectionClass initSec;
string response = initSec.GetResult();
strncpy_s(url, bufferLength, response.c_str(), response.length());
}
}
Now, I would like to be able to create an DLL from this, and I would like to make a test program to call the class and the method GetUrl from a dll. I'm using Visual Studio 2010 with Visual C++ DLL.
I've also managed to read this from the MSDN and this tutorial as well, but I just can't seem to get it to work!
I would really appreciate any help!
Unless I'm mistaken, you don't seem to be giving your class a name.
You made ConnectMe not a class name but a macro to export your class, but your class should have a name
Maybe try
#define EXPORT_IT __declspec( dllexport )
namespace ConnectHttps
{
class EXPORT_IT ConnectMe
{
void GetUrl(char *url, unsigned int bufferLength);
};
}
Also I'm not 100% sure of this because I don't have access to a compiler at the moment, but typing:
namespace ConnectHttps {
...
}
In your .cpp file isn't correct. Instead you should have:
void ConnectHttps::ConnectMe::GetUrl(char* url, unsigned bufferLength)
{
MyConnectionClass initSec;
string response = initSec.GetResult();
strncpy_s(url, bufferLength, response.c_str(), response.length());
}