COM - How to get the properties of an interface within the type library the interface is defined - com

How to get the properties of an interface within the type library the interface is defined, Keeps returning HRESULT but would like it to return the actual value of the property.
EDIT:
IDL:
interface IMyClassInterface : IDispatch
{
[propget, id(1), helpstring("Gets user Type")] HRESULT getUserDefineTypeVal([out,retval] UserDefineEnum *ptrVal);
[propput, id(1), helpstring("Sets user Type ")]HRESULT setUserDefineTypeVal([in] UserDefineEnum newVal);
}
Property in Header File:
STDMETHOD(getUserDefineTypeVal)(UserDefineEnum *ptrVal);
STDMETHOD(setUserDefineTypeVal)(UserDefineEnum newVal);
Property in MYClass.cpp:
STDMETHODIMP CMYClass::getUserDefineTypeVal(UserDefineEnum *ptrVal) {
*ptrVal = UserDefineEnum(private_var_UserDefineTypeVal);
return S_OK;
}
AnotherClass within the Type Library:
IMyClassInterface* private_var_MyClass
STDMETHODIMP CAnotherClass::someMethod(){
UserDefineEnum* p;
if(private_var_MyClass->getUserDefineTypeVal(p)){
//do somestuff
}
}
The problem is the if condition doesn’t return true. However the below partially works.
HRESULT hr = private_var_MyClass->getUserDefineTypeVal(p);
if(hr == S_OK){ do somestuff }
The problem with this is if I attempt a case statement the only value in hr is 0. I need to check the value being set on the clientside.

The value of S_OK is 0, that's why your if() statement doesn't execute. You should use the SUCCEEDED macro:
UserDefinedEnum value;
HRESULT hr = private_var_MyClass->getUserDefineTypeVal(&value);
if (SUCCEEDED(hr)) {
switch (value) {
// etc...
}
}
else {
// do something with the error...
}

COM usually uses out parameters to return values. In C/C++ you have to pass a pointer to a variable which will contain the result upon return.
The HRESULT return parameter is only used to report the success (or failure) of the method call.
EDIT For your code, you need to reserve the memory for the result by the caller:
UserDefineEnum p; // No * here ...
if (private_var_MyClass->getUserDefineTypeValue(&p) == S_OK) { // note '&' operator!
switch (p) {
case ENUM_1: // ...
case ENUM_2:
// ...
}
}

Related

How to call a native method with a std::vector as argument and retrieve the native object in wrapped class

I have a native C++ method, from external unchangable DLL, that expects a std::vector as a argument with 2 native objects. (for example sake, it's an image library returning width/height of a 2 images)
I would like the native objects in the std::vector to be referenced in my own wrapped MyManagedImageObj.
Somehow the std::vector seems to copy values and has no way to add pointers (correct?); so after calling the NativeMethod; I need to copy the properties (width/height) back again to MyManagedImageObj.
I thought about first declaring the std::vec and getting the pointer of the results and put that in MyManagedImageObj as a pointer. But if I understand it correctly std::vector will clean that native memory up once out of scope. (my c++ experience is 1 week; c# long time)
Is there a better way to do this without reassigning the properties one by one?
Ej
The code looks like this:
//create managed object that wraps also native pointer.
MyManagedImageObj^ obj1 = gcnew MyManagedImageObj();
MyManagedImageObj^ obj2 = gcnew MyManagedImageObj();
//keep list of result
List<MyManagedImageObj^>^ resultList;
resultList->Add(obj1);
resultList->Add(obj2);
//call to native method. Dereference pointers of native wrapped objects... not working?
std::vector<DLLNativeImageObj> nativeImageVec { *obj1->GetInstance(), *obj2->GetInstance() };
bool result = otherNativePtr->NativeMethod(nativeImageVec);
//we still need copy it over results now to 'our' managed objects.
int i = 0;
for (DLLNativeImageObj c : nativeImageVec)
{
resultList[i]->ImageHeight = c.imageHeight;
resultList[i]->ImageWidth = c.imageWidth;
++i;
}
The MyManagedImageObj class looks like this:
//MyManagedImageObj.h
public ref class MyManagedImageObj
{
protected:
DLLNativeImageObj* m_Instance;
public:
MyManagedImageObj(DLLNativeImageObj* instance)
: m_Instance(instance)
{
};
~MyManagedImageObj() //destructor will be called whenever we do 'delete'
{
if (m_Instance != nullptr)
{
delete m_Instance;
}
}
!MyManagedImageObj() //finalizer, called by the garbage collector when it's destroys the wrapper object. So safety check to dispose unmanaged item.
{
if (m_Instance != nullptr)
{
delete m_Instance;
}
}
DLLNativeImageObj* GetInstance() //return the pointer to the unmanaged object
{
return m_Instance;
}
property uint32_t ImageWidth
{
public:
uint32_t get()
{
return m_Instance->imageWidth;
}
public:
void set(uint32_t value)
{
m_Instance->imageWidth = value;
}
}
property uint32_t ImageHeight
{
public:
uint32_t get()
{
return m_Instance->imageHeight;
}
public:
void set(uint32_t value)
{
m_Instance->imageHeight = value;
}
}
};
//MyManagedImageObj.cpp
MyManagedImageObj::MyManagedImageObj(new DLLNativeImageObj())
{
// new keyword important: it returns a pointer to the location and does not get deleted when out of scope. Manual delete is required.
}

"Pure" dispinterface marshaling

Update 2021-04-20: The code presented here is for illustration purposes only. As pointed out by Simon Mourier, for marshaling in-process of such a simple class there is no need for all the TLB shenanigans. In reality, the TLB is provided by a third-party, with the interface in question serving for callbacks.
The object calling the interface resides in another process, however, so I really do have to marshal the interface after implementing it. As demonstrating the whole inter-process flow is tedious, I opted for something simpler - in-process inter-apartment marshaling.
Suppose I have the following type library:
import "oaidl.idl";
import "ocidl.idl";
[
uuid(99CF9EB9-9B6E-4D44-B73C-6BB8FCD45B82),
version(1.0),
]
library IsThisRealMarshal
{
[
uuid(80997EA1-0144-41EC-ABCF-5FAD08D5A498),
nonextensible,
]
dispinterface IMyInterface
{
properties:
methods:
[id(1)]
void Method();
};
};
I would like to marshal IMyInterface to another apartment. Since it's a dispinterface, I would like to use the OLE marshaler for this. And so, I register the type library:
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\SOFTWARE\Classes\TypeLib\{99CF9EB9-9B6E-4D44-B73C-6BB8FCD45B82}]
[HKEY_CURRENT_USER\SOFTWARE\Classes\TypeLib\{99CF9EB9-9B6E-4D44-B73C-6BB8FCD45B82}\1.0]
[HKEY_CURRENT_USER\SOFTWARE\Classes\TypeLib\{99CF9EB9-9B6E-4D44-B73C-6BB8FCD45B82}\1.0\0]
[HKEY_CURRENT_USER\SOFTWARE\Classes\TypeLib\{99CF9EB9-9B6E-4D44-B73C-6BB8FCD45B82}\1.0\0\win32]
#="path\\to\\library.tlb"
And the interface (setting the proxy CLSID to that of the OLE marshaler):
Windows Registry Editor Version 5.00
[HKEY_CURRENT_USER\SOFTWARE\Classes\Interface\{80997EA1-0144-41EC-ABCF-5FAD08D5A498}]
[HKEY_CURRENT_USER\SOFTWARE\Classes\Interface\{80997EA1-0144-41EC-ABCF-5FAD08D5A498}\ProxyStubClsid32]
#="{00020424-0000-0000-C000-000000000046}"
[HKEY_CURRENT_USER\SOFTWARE\Classes\Interface\{80997EA1-0144-41EC-ABCF-5FAD08D5A498}\TypeLib]
#="{99CF9EB9-9B6E-4D44-B73C-6BB8FCD45B82}"
"Version"="1.0"
And I try to marshal (error-checking omitted for brevity):
CoInitializeEx(nullptr, COINIT_MULTITHREADED);
CComPtr<IMyInterface> object {};
object.Attach(new MyObject);
CComPtr<IGlobalInterfaceTable> git {};
git.CoCreateInstance(CLSID_StdGlobalInterfaceTable, nullptr, CLSCTX_INPROC_SERVER);
DWORD cookie = 0;
git->RegisterInterfaceInGlobal(object, __uuidof(IMyInterface), &cookie);
auto thread = std::thread([cookie]
{
CoInitializeEx(nullptr, COINIT_APARTMENTTHREADED);
CComPtr<IGlobalInterfaceTable> git {};
git.CoCreateInstance(CLSID_StdGlobalInterfaceTable, nullptr, CLSCTX_INPROC_SERVER);
CComPtr<IMyInterface> object {};
git->GetInterfaceFromGlobal(cookie, __uuidof(IMyInterface), (void **)&object);
});
thread.join();
Where the MyObject class implements the bare minimum COM functionality:
class MyObject : public IMyInterface
{
private:
std::atomic<ULONG> _refcount = 1;
public:
MyObject() = default;
MyObject(MyObject const &) = delete;
MyObject & operator=(MyObject const &) = delete;
HRESULT QueryInterface(const IID& riid, void** ppvObject) override
{
if (nullptr == ppvObject)
{
return E_POINTER;
}
if (riid == __uuidof(IUnknown))
{
*ppvObject = static_cast<IUnknown *>(this);
}
else if (riid == __uuidof(IDispatch))
{
*ppvObject = static_cast<IDispatch *>(this);
}
else if (riid == __uuidof(IMyInterface))
{
*ppvObject = static_cast<IMyInterface *>(this);
}
else
{
*ppvObject = nullptr;
return E_NOINTERFACE;
}
static_cast<IUnknown *>(*ppvObject)->AddRef();
return S_OK;
}
ULONG AddRef() override
{
return ++_refcount;
}
ULONG Release() override
{
auto const new_refcount = --_refcount;
if (0 == new_refcount)
{
delete this;
}
return new_refcount;
}
HRESULT GetTypeInfoCount(UINT* pctinfo) override
{
return E_NOTIMPL;
}
HRESULT GetTypeInfo(UINT iTInfo, LCID lcid, ITypeInfo** ppTInfo) override
{
return E_NOTIMPL;
}
HRESULT GetIDsOfNames(const IID& riid, LPOLESTR* rgszNames, UINT cNames, LCID lcid, DISPID* rgDispId) override
{
return E_NOTIMPL;
}
HRESULT Invoke(DISPID dispIdMember, const IID& riid, LCID lcid, WORD wFlags, DISPPARAMS* pDispParams,
VARIANT* pVarResult, EXCEPINFO* pExcepInfo, UINT* puArgErr) override
{
return E_NOTIMPL;
}
};
Unfortunately, the call to GetInterfaceFromGlobal fails with E_FAIL.
Debugging reveals that none of the IDispatch methods are called, only the IUnknown ones. Additionally, it appears that the E_FAIL originates from combase!CheckTypeInfo. First, this function uses ITypeInfo::GetTypeAttr to retrieve information about IMyInterface:
It then proceeds to check whether the flags TYPEFLAG_FDUAL (0x40) or TYPEFLAG_FOLEAUTOMATION (0x100) are present in the wTypeFlags field of the TYPEATTR structure:
Since neither of these flags are present (the field has the value 0x1080, and indeed the IDL doesn't mark the interface as either [oleautomation] or [dual]), the function fails with E_FAIL.
What am I doing wrong? And if the OLE marshaler indeed cannot marshal this interface, is there anything I can do apart from implementing IMarshal myself, assuming I cannot modify the IDL?
With the help of Simon Mourier's code, I managed to find the problem. The problem was that I used the PSOAInterface proxy ({00020424-0000-0000-C000-000000000046}). Since IMyInterface is not an OLE Automation interface (i.e. not marked with [oleautomation]), this rightly failed.
The solution is to use the PSDispatch proxy ({00020420-0000-0000-C000-000000000046}), which is capable of marshaling pure IDispatch interfaces.

Is there any concern about returning generic type object in Dart?

I want to implement a different error handling approach in a project without chaining exceptions.
To make it simple as possible, I am tend to write my own basic either-like model.
class Either<F, T> {
final F failure;
final T value;
const Either(this.failure, this.value);
Object check (){
if (failure != null) return failure;
return value;
}
}
I am concerning about returning the type Object, is there any problem or considerations with that in Dart or any other language?
Edit:
or returning dynamic type...
dynamic check(){
if (failure != null) return failure;
return value;
}
I think in your case, it's kind of a wired implementation. The question is, what do you want to do with the actual implementation ? Do you want to replace an if else that will appear over and over? In that case, what would you do if you have to handle the error (failure) ? I think a better approach is to use functions as parameters. Here's a short suggestion.
class Either<T, F> {
T value;
F fail;
Either(this.value, this.fail);
void check(success(T value), {failure(F fail)}) {
if (fail != null && failure != null) {
failure(fail);
} else if (value != null) {
success(value);
}
}
}
class SomeClass {
void checkTheImplementation() {
Either<String, Error> maybeString = Either("testing", null);
// if you don't want to handle the error.
maybeString.check((value) => print(value));
// if you want to handle the error
maybeString.check((value) => print(value), failure: (err) {
print(err.toString());
});
}
}
I have looked over and decided to go with baihu92's either_type way. It's much more clear and comprehensible than either in the dartz package. Here is my implementation:
and the usage is like:

Simple convert C++/CLI int^ to unmanaged int*

This is so basic it should be easy to find. In my searches all I get is more complex solutions. Converting strings, marshaling, pinning objects. How do you simply convert from a c++/CLI int^ pointer to a native int* in C++/CLI.
The body of my function is
void Open(int ^Hndl)
{
void Unmanaged_Open(Hndl); // How do you pass the pointer to this
}
where
void Unmanaged_Open(int *handle);
Here is how you implement an output parameter in C++/CLI, like C#'s void func(out int x). Note that there is no int^.
void Open([OutAttribute] int% retval)
{
int result;
if (!UnmanagedOpen(&result))
throw gcnew Exception("Open failed!");
retval = result;
}
Note that it is probably even better to simply return the value. Out parameters most appear in native functions when the return value is used for error checking. You can either use exceptions in .NET for error-checking, like so:
int Open()
{
int result;
if (!UnmanagedOpen(&result))
throw gcnew Exception("Open failed!");
return result;
}
or if failure is expected (untrusted input, for example), implement the TryXYZ pattern (described on MSDN):
bool TryOpen([OutAttribute] int% retval)
{
retval = 0;
int result;
if (!UnmanagedOpen(&result)) return false;
retval = result;
return true;
}

Return Value from Function Swift

I know this is probably a simple queston, I would like to return the value of currentLocGeoPoint and return the array of Objects which is of type PFObject.
Tried to save it as a global variable, but it doesn't work because it is asynchronous and doesn't take a value yet. Returns empty.
Tried to return currentLocGeoPoint and changed Void in to PFGeoPoint in. Gives error: PFGeoPoint is not convertible to 'Void'
So I'm not sure how I can fetch the variable currentLocGeoPoint.
func locationManager(manager: CLLocationManager!, didUpdateLocations locations: [AnyObject]!) {
CLGeocoder().reverseGeocodeLocation(manager.location, completionHandler: { (placemarks, error) -> Void in
if (error != nil) {
println("Error:" + error.localizedDescription)
//return
}
if placemarks.count > 0 {
let pm = placemarks[0] as CLPlacemark
self.displayLocationInfo(pm)
currentLoc = manager.location
currentLocGeoPoint = PFGeoPoint(location:currentLoc)
var query = PFQuery(className:"Bar")
query.whereKey("BarLocation", nearGeoPoint:currentLocGeoPoint, withinMiles:10)
query.limit = 500
query.findObjectsInBackgroundWithBlock {
(objects: [AnyObject]!, error: NSError!) -> Void in
if objects != nil {
} else {
println("error: \(error)")
}
}
} else {
println("error: \(error)")
}
})
}
I don't understand the notion of "I want to return currentLocGeoPoint". Return it to what? You're in a CLLocationManagerDelegate method, so there's no one to return it to.
What you could do, though, is, when the request is done (i.e. within this closure), call some other function that needed the currentLocGeoPoint. Or you could update the UI to reflect the updated information (make sure to dispatch that update to the main thread, though). Or, if you have other view controllers or model objects that need to know about the new data, you might post a notification, letting them know that there is an updated currentLocGeoPoint. But within this method, there's no one to whom you would "return" the data.
You could assign it to a stored property of your class. Just use
self.<property> = currentLocGeoPoint