Click here to Skip to main content
Rate this: bad
good
Please Sign up or sign in to vote.
See more: C++ ATL DLL
hi,
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;
}
STDMETHODIMP CInterfaceForClassA::getClassA(VARIANT** pVal)
{
         *pVal = (VARIANT*)Aobject;
          return S_OK;
}
STDMETHODIMP CInterfaceForClassA::putClassA(VARIANT* newVal)
{
         Aobject = (ClassA*)newVal;
         return S_OK;
}
InterfaceForClassB :
STDMETHODIMP CInterfaceForClassB::setClassA(IInterfaceForClassA * val)
{
 
          ClassB* BObject = new ClassB();
          ClassA* objA = new ClassA();            
         val->getClassA((VARIANT**)&objA);
         BObject->putClassA(objA);
          return S_OK;
}
 
STDMETHODIMP CInterfaceForClassB::getClassA(IInterfaceForClassA ** returnVal)
{
          ClassA* objA = new ClassA();   
          IInterfaceForClassA *pY;
          objA = BObject->getClassA();        
          pY->putClassA((VARIANT*)&objA);
          *returnVal = pY;
          return S_OK;
}
and finally i have a c# project that includes that ATL dll, in the c# project i call ATL dll classes:
InterfaceForClassAClass classAInt = new InterfaceForClassAClass();
classAInt.createClassAObject();
classAInt.setNumberInClassA(5);
InterfaceForClassBClass classBInt = new InterfaceForClassBClass();
classBInt.setClassA(classAInt);
classBInt.getClassA();
it gives the 'System.ExecutionEngineException' at the line "classBInt.getClassA();" .
Can you help me please?
Posted 16-Mar-10 0:50am
bltfr448
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 1

An uninitialized pointer pY will be used... Smile | :)
class CInterfaceForClassB
{
  IInterfaceForClassA* m_pInterfaceA;
 
public:
  CInterfaceForClassB();
 
  STDMETHODIMP SetInterfaceA(IInterfaceForClassA* val);
  STDMETHODIMP GetInterfaceA(IInterfaceForClassA* val);
};
 
CInterfaceForClassB::CInterfaceForClassB()
  : m_pInterfaceA(NULL)
{
}
 
STDMETHODIMP CInterfaceForClassB::SetInterfaceA(IInterfaceForClassA* val)
{
  m_pInterfaceA = val;
}
 
STDMETHODIMP CInterfaceForClassB::GetInterfaceA(IInterfaceForClassA* val)
{
  val = m_pInterfaceA;
}
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 2

thank you for your answer.
but it gives the following error:
 
" [out] interface pointers must use double indirection : [ Parameter 'val' of Procedure 'getInterfaceA' ( Interface 'IInterfaceForClassB' ) ] "
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 3

OK Smile | :)
 
Try to change your get function:
STDMETHODIMP CInterfaceForClassB::GetInterfaceA(IInterfaceForClassA** val)
{
  *val = m_pInterfaceA;
}
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 4

it builds the dll without error but in the c# side:
InterfaceForClassAClass classAInt = new InterfaceForClassAClass();
classAInt.createClassAObject();
classAInt.setNumberInClassA(5);
InterfaceForClassBClass classBInt = new InterfaceForClassBClass();
classBInt.setClassA(classAInt);
 
InterfaceForClassAClass classAInt2 = new InterfaceForClassAClass();
classAInt2 = classBInt.getClassA();
 
it gives following error at the last line:
" Cannot implicitly convert type 'myATLprojectLib.InterfaceForClassA' to 'myATLprojectLib.InterfaceForClassAClass'. An explicit conversion exists (are you missing a cast?) "
 
then i changed the code to :
InterfaceForClassA classAInt2 = new InterfaceForClassA();
classAInt2 = classBInt.getClassA();
Console.WriteLine("Number "+ classAInt2.getNumberInClassA());
this time it gives the following error at the last line:
"AccessViolationException :Attempted to read or write protected memory. This is often an indication that other memory is corrupt."
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 5

There are some things to improve in your classA... Smile | :)

But, firstly, improve and try it, please Smile | :) :
{
  InterfaceForClassAClass classAInt = new InterfaceForClassAClass();
  InterfaceForClassBClass classBInt = new InterfaceForClassBClass();
  
  classBInt.SetInterfaceA(classAInt);    // now is the pointer stored by B

  InterfaceForClassAClass classAInt2;    // second empty "pointer"

  classBInt.GetInterfaceA(&classAInt2);  // reference of the "pointer" in C# ??
                                         // classAInt2 = classAInt 

}
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 6

i try it and it gives following errors at line "classBInt.GetInterfaceA(&classAInt2);"
 
"Cannot take the address of, get the size of, or declare a pointer to a managed type ('myATLprojectLib.InterfaceForClassAClass') "
"No overload for method 'GetInterfaceA' takes '1' arguments "
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 7

OK Smile | :)
 
Could you post your IDL file (of the COM DLL), please,
and the result for:
{
...
  // the same above, and then:
  InterfaceForClassAClass classAInt2 = classBInt.GetInterfaceA();
}
  Permalink  
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 8

The result for the above code:
" Cannot implicitly convert type 'myATLprojectLib.InterfaceForClassA' to 'myATLprojectLib.InterfaceForClassAClass'. An explicit conversion exists (are you missing a cast?) ", it gives it at the last line.
 
my idl:
import "oaidl.idl";
import "ocidl.idl";
 

[
    object,
    uuid(B825F096-A558-4751-BC3E-13CA91AB08E3),
    dual,
    nonextensible,
    helpstring("IInterfaceForClassA Interface"),
    pointer_default(unique)
]
interface IInterfaceForClassA : IDispatch{
    [id(1), helpstring("method createClassAObject")] HRESULT createClassAObject(void);
    [id(2), helpstring("method setNumberInClassA")] HRESULT setNumberInClassA([in]SHORT pVal);
    [id(3), helpstring("method getNumberInClassA")] HRESULT getNumberInClassA([out,retval]SHORT* pVal);
    [id(4), helpstring("method getClassA")] HRESULT getClassA([out,retval]VARIANT** pVal);
    [id(5), helpstring("method putClassA")] HRESULT putClassA([in]VARIANT* newVal);
 
};
[
    object,
    uuid(F6D4B1A3-BA23-4499-92B6-8CC815F45107),
    dual,
    nonextensible,
    helpstring("IInterfaceForClassB Interface"),
    pointer_default(unique)
]
interface IInterfaceForClassB : IDispatch{
    [id(1), helpstring("method setClassA")] HRESULT setClassA([in]IInterfaceForClassA * val)
    [id(2), helpstring("method getClassA")] HRESULT getClassA([out,retval]IInterfaceForClassA ** returnVal)
 
};
[
    uuid(19E570BC-88E1-4EA1-BEBB-55B113C0B71A),
    version(1.0),
    helpstring("myATLproject 1.0 Type Library")
]
library myATLprojectLib
{
    importlib("stdole2.tlb");
    [
        uuid(5A01A221-647A-4FCC-A2AD-2ADF0DA4895B),
        helpstring("InterfaceForClassB Class")
    ]
    coclass InterfaceForClassB
    {
        [default] interface IInterfaceForClassB;
    };
    [
        uuid(D3ACED71-F62A-43FF-AC69-994222D93308),
        helpstring("InterfaceForClassA Class")
    ]
    coclass InterfaceForClassA
    {
        [default] interface IInterfaceForClassA;
    };
);
  Permalink  
v3
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 9

Here would be my suggestion Smile | :) :
 
// C++ DLL.h
class A
{
  int m_iNumber;
public:
  A()                               { m_iNumber = 0; };
  void SetNumber(const int& iValue) { m_iNumber = iValue; };
  int  GetNumber()                  { return m_iNumber; };
  const A& operator = (const A& a)  { m_iNumber = a.GetNumber(); return *this; };
};
class B
{
  A m_aProperty;
public:
  B()                                {};
  void SetProperty(const A& a)       { m_aProperty = a; };
  const A& GetProperty()             { return m_aProperty; };
};
 
// ATL DLL.h
#include "C++ DLL.h"
 
class CInterfaceA
{
  DWORD m_dwID;
  A     m_aProperty;
 
public:
  CInterfaceA();
  ~CInterfaceA();
 
  const A& GetProperty();
 
  STDMETHODIMP SetNumber(SHORT shNumber);
  STDMETHODIMP GetNumber(SHORT* pshNumber);
  STDMETHODIMP GetID(ULONG* pulID);
};
 
class CInterfaceB
{
  B m_bProperty;
 
public:
  CInterfaceB();
 
  STDMETHODIMP SetAByID(ULONG ulID);
};
 
// ATL DLL.cpp
#include "ATL DLL.h"
#include <atlsimpcoll.h>
 
DWORD g_dwAObjectsCount = 0;
CSimpleMap<DWORD, CInterfaceA*> g_AObjectsMap;
 
CInterfaceA::CInterfaceA()
{
  m_dwID = g_dwAObjectsCount++;
  g_AObjectsMap.SetAt(m_dwID, this);
}
 
CInterfaceA::~CInterfaceA()
{
  g_AObjectsMap.RemoveAt(m_dwID);
}
 
const A& CInterfaceA::GetProperty()
{
  return m_aProperty;
}
 
STDMETHODIMP CInterfaceA::SetNumber(SHORT shNumber)
{
  m_aProperty.SetNumber(shNumber);
  return S_OK;
}
  
STDMETHODIMP CInterfaceA::GetNumber(SHORT* pshNumber)
{
  *pshNumber = m_aProperty.GetNumber();
  return S_OK;
}
  
STDMETHODIMP CInterfaceA::GetID(ULONG* pulID)
{
  *pulID = m_dwID;
  return S_OK;
}
  
 
CInterfaceB::CInterfaceB()
{
}
 
STDMETHODIMP CInterfaceB::SetAByID(ULONG ulID)
{
  CInterfaceA* pcInterfaceA = g_AObjectsMap.GetValueAt(ulID);
  if (pcInterfaceA) {
    A a = pcInterfaceA->GetProperty();
    m_bProprerty.SetProperty(a);
  }
  return S_OK;
}
 
// C# usage
{
...
  InterfaceForClassAClass classAInt = new InterfaceForClassAClass();
  classAInt.SetNumber(5);
  ULONG ulID = 0;
  classAInt.GetID(&ulID);
  
  InterfaceForClassBClass classBInt = new InterfaceForClassBClass();
  classBInt.SetAByID(ulID); // IB::m_bProperty::m_aProperty = IA::m_aProperty :)
...
}
  Permalink  
v2
Rate this: bad
good
Please Sign up or sign in to vote.

Solution 10

Eugen thanks for your answer. but i couldn't do it, i can't modify c++ dll and other stuff didn't work. I suppose i should find another way to solve this problem.Thanks again for your all effort
  Permalink  

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS
0 OriginalGriff 250
1 George Jonsson 175
2 Jochen Arndt 150
3 Kornfeld Eliyahu Peter 149
4 PIEBALDconsult 110
0 OriginalGriff 6,080
1 DamithSL 4,648
2 Maciej Los 4,087
3 Kornfeld Eliyahu Peter 3,624
4 Sergey Alexandrovich Kryukov 3,294


Advertise | Privacy | Mobile
Web04 | 2.8.141220.1 | Last Updated 26 Mar 2010
Copyright © CodeProject, 1999-2014
All Rights Reserved. Terms of Service
Layout: fixed | fluid

CodeProject, 503-250 Ferrand Drive Toronto Ontario, M3C 3G8 Canada +1 416-849-8900 x 100