I have a native C++ dll and two classes:
classA
{
void setNumber(int number);
int getNumber();
}
classB
{
void setclassA(classA*);
classA* getclassA();
}
I have an ATL dll that wraps the native C++ dll and two interfaces: InterfaceForClassA , InterfaceForClassB .
InterfaceForClassA :
STDMETHODIMP CInterfaceForClassA::createClassAObject(void)
{
ClassA* Aobject = new ClassA();
return S_OK;
}
STDMETHODIMP CInterfaceForClassA::setNumberInClassA(SHORT pVal)
{
if(Aobject != NULL)
Aobject->setNumber(pVal);
return S_OK;
}
STDMETHODIMP CInterfaceForClassA::getNumberInClassA(SHORT* pVal)
{
if(Aobject != NULL)
*pVal = Aobject->getNumber();
return S_OK;
}
InterfaceForClassB :
IInterfaceForClassA* clsAInterface;
STDMETHODIMP CInterfaceForClassB::setClassA(IInterfaceForClassA * val)
{
val->QueryInterface(IID_IInterfaceForClassA,(void**)clsAInterface;
}
STDMETHODIMP CInterfaceForClassB::getClassA(IInterfaceForClassA ** returnVal)
{
clsAInterface->QueryInterface(IID_IInterfaceForClassA,(void**)returnVal);
}
and finally i have a c# project that includes the ATL dll, in the c# project i call ATL dll classes:
InterfaceForClassA clsa1 = new InterfaceForClassA();
clsa1.createClassAObject();
clsa1.setNumberInClassA(12);
InterfaceForClassB clsb = new InterfaceForClassB();
clsb.setClassA(clsa1);
InterfaceForClassA clsa2 = new InterfaceForClassA();
clsa2 = clsb.getClassA();
Console.WriteLine("number: " + clsa2.getNumberInClassA());
and when i run the c# project, it gives NullReferenceException error in the last line above. Can you help me?
Your CInterfaceForClassB::setClassA implementation is incorrect. It should be (note the &):
STDMETHODIMP CInterfaceForClassB::setClassA(IInterfaceForClassA * val)
{
val->QueryInterface(IID_IInterfaceForClassA,(void**)&clsAInterface);
}
Related
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.
I have a large solution with 50+ unmanaged projects in it. I have recently added a project with managed code in it to the solution. The managed code accesses Windows.Devices.Sensors in a .NET dll. This dll is eventually wrapped by unmanaged code and called from another unmanaged project.
My problem is that I get the following access violation before main() even executes.
Unhandled exception at 0x744b8ea0 in myApplication.exe: 0xC0000005: Access violation.
Managed code:
#using <Windows.winmd>
using namespace Windows::Devices::Sensors;
#include <math.h>
namespace TabletSensors
{
namespace NET
{
public ref class DotNetDllClass
{
public:
DotNetDllClass()
{
Initialization();
}
~DotNetDllClass()
{
}
float* GetQuaternion()
{
OrientationSensorReading^ reading = _orientation->GetCurrentReading();
if( reading != nullptr )
{
float* quat = new float[4];
quat[0] = reading->Quaternion->X;
quat[1] = reading->Quaternion->Y;
quat[2] = reading->Quaternion->Z;
quat[3] = reading->Quaternion->W;
return quat;
}
else
{
return NULL;
}
}
private:
void Initialization()
{
_orientation = OrientationSensor::GetDefault();
if( _orientation != nullptr )
{
_orientation->ReportInterval = 16;
}
else
{
// not good ... throw exception or something
}
}
OrientationSensor^ _orientation;
};
}
}
Wrapper header file:
namespace TabletSensors
{
namespace NETWrapper
{
class DLLEXPORT_SENSORS WrapperClass
{
public:
__stdcall WrapperClass();
__stdcall ~WrapperClass();
float* __stdcall GetQuaternion();
};
}
}
Wrapper cpp file:
#define MIXSENSORS_BUILD
#include <gcroot.h>
#include "DotNetWrapper.h"
#include "DotNetDll.h"
using namespace TabletSensors::NETWrapper;
using namespace TabletSensors::NET;
static gcroot<TabletSensors::NET::DotNetDllClass^> Sensors = nullptr;
static System::UInt16 refCount = 0;
#pragma managed
inline TabletSensors::NET::DotNetDllClass^ GetSensors(void)
{
return (TabletSensors::NET::DotNetDllClass^)Sensors;
}
void Init()
{
++refCount;
if(GetSensors() == nullptr)
{
Sensors = gcnew TabletSensors::NET::DotNetDllClass();
}
}
void CleanUp()
{
if( refCount > 0 )
{
--refCount;
}
}
float* GetQuaternion_()
{
return Sensors->GetQuaternion();
}
#pragma unmanaged
TabletSensors::NETWrapper::WrapperClass::WrapperClass()
{
Init();
}
TabletSensors::NETWrapper::WrapperClass::~WrapperClass()
{
CleanUp();
}
float* TabletSensors::NETWrapper::WrapperClass::GetQuaternion()
{
float* x = new float[4];
return GetQuaternion_();
}
#pragma managed
Unmanaged project referencing my wrapper class:
#include "DotNetWrapper.h"
.
.
.
void UnmanagedProject::Update()
{
// if this line is present, I get an access violation without hitting any breakpoints.
TabletSensors::NETWrapper::WrapperClass _tabletSensors;
.
.
.
}
Since the managed code is trying to access Tablet Sensors I understand why it doesn't work on my Windows 7 desktop. What I don't understand it why it won't even allow me to debug my code at all. No breakpoints are hit before the Access Violation occurs.
What I would really like to figure out is how to use exception handling or #ifdefs to keep this crash from happening. But I have had very little luck.
Any ideas?
The fix is to Delay Load the managed DLL. The allows the application to run until that DLL is explicitly called. Thanks to Ben Voight for his answer here: https://stackoverflow.com/a/28467701/1454861
I have written MFC dll having 3 methods are exported. I have declared class object as global and initialized it in first method then second and third method use and process it.
Issue is that class obeject's value is not getting persisting throughout the file. when second or third method gets call from C# client application, class
object value is getting NULL.
Could anybody tell me why this is happening! I have tried this same scnaerio in another application but this issue is not reproduced.
Code:
Interface File:
#include "StdAfx.h"
#define DLLEXPORT __declspec(dllexport)
using namespace nsAnalyzer;
static CWindowsAnalyzer *pWindowsAnalyzer = NULL;
extern "C" DLLEXPORT void Init( const wchar_t *sCurrentUserDataDir,
const wchar_t *sMachineName,
const wchar_t *sMacId )
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
try
{
nsAnalyzer::CWindowsAnalyzer *pWindowsAnalyzer = new CWindowsAnalyzer( CString(sCurrentUserDataDir),
CString(sMachineName),
CString(sMacId) );
if(pWindowsAnalyzer)
{
pWindowsAnalyzer->Init();
}
}
catch(const std::exception& e)
{
cout<<"Error: Exception occured in Init: "<<e.what()<<endl;
}
}
extern "C" DLLEXPORT bool Analyze()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
bool bResult = false;
try
{
if(pWindowsAnalyzer->ConsolidateRawActivities())
{
cout<<"ConsolidateRawActivities succeed"<<endl;
bResult = true;
}
else
{
cout<<"ConsolidateRawActivities failed"<<endl;
bResult = false;
}
}
catch(const std::exception& e)
{
cout<<"Error: Exception occured in Analyze: "<<e.what()<<endl;
}
return bResult;
}
extern "C" DLLEXPORT void Dispose()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
try
{
// Disponse windows analyzer
if(pWindowsAnalyzer)
{
delete pWindowsAnalyzer;
}
// Dispose Logger
CLogger::DisposeInstance();
}
catch(const std::exception& e)
{
cout<<"Error: Exception occured in Dispose: "<<e.what()<<endl;
}
}
What is the basic structure of a wrapper to c++/cli so it can be called from c# ?
A wrapper for a C++ class Blah:
EDIT:
ref class BlahWrapper {
BlahWrapper () {
blah = new Blah();
}
!BlahWrapper() { //Destructor called by GC
if (blah != null) {
delete blah;
blah = null;
}
}
~BlahWrapper() { //Dispose() called in "using" blocks, or manually dispose
if (blah != null) {
delete blah;
blah = null;
}
}
private:
Blah* blah;
}
I'm wanting to have a simple duck typing example in C# using dynamic objects. It would seem to me, that a dynamic object should have HasValue/HasProperty/HasMethod methods with a single string parameter for the name of the value, property, or method you are looking for before trying to run against it. I'm trying to avoid try/catch blocks, and deeper reflection if possible. It just seems to be a common practice for duck typing in dynamic languages (JS, Ruby, Python etc.) that is to test for a property/method before trying to use it, then falling back to a default, or throwing a controlled exception. The example below is basically what I want to accomplish.
If the methods described above don't exist, does anyone have premade extension methods for dynamic that will do this?
Example: In JavaScript I can test for a method on an object fairly easily.
//JavaScript
function quack(duck) {
if (duck && typeof duck.quack === "function") {
return duck.quack();
}
return null; //nothing to return, not a duck
}
How would I do the same in C#?
//C# 4
dynamic Quack(dynamic duck)
{
//how do I test that the duck is not null,
//and has a quack method?
//if it doesn't quack, return null
}
If you have control over all of the object types that you will be using dynamically, another option would be to force them to inherit from a subclass of the DynamicObject class that is tailored to not fail when a method that does not exist is invoked:
A quick and dirty version would look like this:
public class DynamicAnimal : DynamicObject
{
public override bool TryInvokeMember(InvokeMemberBinder binder, object[] args, out object result)
{
bool success = base.TryInvokeMember(binder, args, out result);
// If the method didn't exist, ensure the result is null
if (!success) result = null;
// Always return true to avoid Exceptions being raised
return true;
}
}
You could then do the following:
public class Duck : DynamicAnimal
{
public string Quack()
{
return "QUACK!";
}
}
public class Cow : DynamicAnimal
{
public string Moo()
{
return "Mooooo!";
}
}
class Program
{
static void Main(string[] args)
{
var duck = new Duck();
var cow = new Cow();
Console.WriteLine("Can a duck quack?");
Console.WriteLine(DoQuack(duck));
Console.WriteLine("Can a cow quack?");
Console.WriteLine(DoQuack(cow));
Console.ReadKey();
}
public static string DoQuack(dynamic animal)
{
string result = animal.Quack();
return result ?? "... silence ...";
}
}
And your output would be:
Can a duck quack?
QUACK!
Can a cow quack?
... silence ...
Edit: I should note that this is the tip of the iceberg if you are able to use this approach and build on DynamicObject. You could write methods like bool HasMember(string memberName) if you so desired.
Try this:
using System.Linq;
using System.Reflection;
//...
public dynamic Quack(dynamic duck, int i)
{
Object obj = duck as Object;
if (duck != null)
{
//check if object has method Quack()
MethodInfo method = obj.GetType().GetMethods().
FirstOrDefault(x => x.Name == "Quack");
//if yes
if (method != null)
{
//invoke and return value
return method.Invoke((object)duck, null);
}
}
return null;
}
Or this (uses only dynamic):
public static dynamic Quack(dynamic duck)
{
try
{
//invoke and return value
return duck.Quack();
}
//thrown if method call failed
catch (RuntimeBinderException)
{
return null;
}
}
Implementation of the HasProperty method for every IDynamicMetaObjectProvider WITHOUT throwing RuntimeBinderException.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Dynamic;
using Microsoft.CSharp.RuntimeBinder;
using System.Linq.Expressions;
using System.Runtime.CompilerServices;
namespace DynamicCheckPropertyExistence
{
class Program
{
static void Main(string[] args)
{
dynamic testDynamicObject = new ExpandoObject();
testDynamicObject.Name = "Testovaci vlastnost";
Console.WriteLine(HasProperty(testDynamicObject, "Name"));
Console.WriteLine(HasProperty(testDynamicObject, "Id"));
Console.ReadLine();
}
private static bool HasProperty(IDynamicMetaObjectProvider dynamicProvider, string name)
{
var defaultBinder = Binder.GetMember(CSharpBinderFlags.None, name, typeof(Program),
new[]
{
CSharpArgumentInfo.Create(
CSharpArgumentInfoFlags.None, null)
}) as GetMemberBinder;
var callSite = CallSite<Func<CallSite, object, object>>.Create(new NoThrowGetBinderMember(name, false, defaultBinder));
var result = callSite.Target(callSite, dynamicProvider);
if (Object.ReferenceEquals(result, NoThrowExpressionVisitor.DUMMY_RESULT))
{
return false;
}
return true;
}
}
class NoThrowGetBinderMember : GetMemberBinder
{
private GetMemberBinder m_innerBinder;
public NoThrowGetBinderMember(string name, bool ignoreCase, GetMemberBinder innerBinder) : base(name, ignoreCase)
{
m_innerBinder = innerBinder;
}
public override DynamicMetaObject FallbackGetMember(DynamicMetaObject target, DynamicMetaObject errorSuggestion)
{
var retMetaObject = m_innerBinder.Bind(target, new DynamicMetaObject[] {});
var noThrowVisitor = new NoThrowExpressionVisitor();
var resultExpression = noThrowVisitor.Visit(retMetaObject.Expression);
var finalMetaObject = new DynamicMetaObject(resultExpression, retMetaObject.Restrictions);
return finalMetaObject;
}
}
class NoThrowExpressionVisitor : ExpressionVisitor
{
public static readonly object DUMMY_RESULT = new DummyBindingResult();
public NoThrowExpressionVisitor()
{
}
protected override Expression VisitConditional(ConditionalExpression node)
{
if (node.IfFalse.NodeType != ExpressionType.Throw)
{
return base.VisitConditional(node);
}
Expression<Func<Object>> dummyFalseResult = () => DUMMY_RESULT;
var invokeDummyFalseResult = Expression.Invoke(dummyFalseResult, null);
return Expression.Condition(node.Test, node.IfTrue, invokeDummyFalseResult);
}
private class DummyBindingResult {}
}
}
impromptu-interface seems to be a nice Interface mapper for dynamic objects... It's a bit more work than I was hoping for, but seems to be the cleanest implementation of the examples presented... Keeping Simon's answer as correct, since it is still the closest to what I wanted, but the Impromptu interface methods are really nice.
The shortest path would be to invoke it, and handle the exception if the method does not exist. I come from Python where such method is common in duck-typing, but I don't know if it is widely used in C#4...
I haven't tested myself since I don't have VC 2010 on my machine
dynamic Quack(dynamic duck)
{
try
{
return duck.Quack();
}
catch (RuntimeBinderException)
{ return null; }
}
Have not see a correct answer here, MS provides an example now with casting to a dictionary
dynamic employee = new ExpandoObject();
employee.Name = "John Smith";
employee.Age = 33;
foreach (var property in (IDictionary<String, Object>)employee)
{
Console.WriteLine(property.Key + ": " + property.Value);
}
// This code example produces the following output:
// Name: John Smith
// Age: 33