Porting a C++ ATL/COM project to C#

  • Thread starter zorrothefox.groups
  • Start date
Z

zorrothefox.groups

Hi,
I'm currently involved in porting a ATL COM dll project to
C#. For compatibility reasons, the signatures of the functions in the
exported .TLB file should remain the same when ported to C#. For the
majority, this seems to be a smooth process.

However, two functions in the Old COM project seem to be giving me a
hard time during porting. One function WriteBytes() basically takes in
a BYTE array, and transfers the values in the array to the Serial
Port. Similarly, ReadBytes() takes a BYTE array as a parameter, and
copies the values read in from the Serial Port into the array.

The function signatures for the ATL COM project are as below...

HRESULT ReadBytes([in]VARIANT *varBuffer, [in]long lNoOfBytes,
[out,retval]long* lBytesRead);
HRESULT WriteBytes([in]VARIANT *varBuffer, [in]long lNoOfBytes,
[out,retval]long* lBytesWritten);

Internally, what the old project does is..
BYTE buffer[512];
long retval=0;

_variant_t *varBuffer = new _variant_t;
varBuffer->byref = buffer;

pSerialInterface->ReadBytes(varBuffer,512,&retval);


Since C# does not support the VARIANT datatype, I declared the
functions in C# as members of an interface that I implement, as below.
Int32 ReadBytes(ref Object pOb, Int32 lNoOfBytes);
Int32 WriteBytes(ref Object pOb, Int32 lNoOfBytes);

My problem is, how do I convert the Object reference properly, so that
I get the base addresses of the arrays being passed in as VARIANT *.

Please help me out here...

Thanks in advance,
Bharat.
 
L

lightdoll

hello zorrothefox

can i ask you something .
Since C# does not support the VARIANT datatype, I declared the
functions in C# as members of an interface that I implement, as below.
Int32 ReadBytes(ref Object pOb, Int32 lNoOfBytes);
Int32 WriteBytes(ref Object pOb, Int32 lNoOfBytes);

==> why did you declared the function
==> because if you use tlbimp with your com, then you will get *.dll make by
tblimp
==> And you can add the dll as refereced ,
==> then you can see the function in C#.
==> i think you don't need to write the function by manual.
==> i have written some code as below
==> this code was made by tlbimp.
public class EasyBridgeClass : IEasyBridge, EasyBridge,
_IEasyBridgeEvents_Event
{
public EasyBridgeClass();

public virtual event
_IEasyBridgeEvents_OnCreateCompositionEventHandler OnCreateComposition;
public virtual event _IEasyBridgeEvents_OnEventNotifyEventHandler
OnEventNotify;
public virtual event
_IEasyBridgeEvents_OnExceptionNotifyEventHandler OnExceptionNotify;
public virtual event
_IEasyBridgeEvents_OnGroupParameterValueEventHandler OnGroupParameterValue;
public virtual event
_IEasyBridgeEvents_OnParameterNotifyEventHandler OnParameterNotify;
public virtual event _IEasyBridgeEvents_OnSetEventIdEventHandler
OnSetEventId;
public virtual event _IEasyBridgeEvents_OnSetExceptionIdEventHandler
OnSetExceptionId;
public virtual event
_IEasyBridgeEvents_OnSetParameterValueEventHandler OnSetParameterValue;
public virtual event _IEasyBridgeEvents_OnSetStartInCompEventHandler
OnSetStartInComp;
public virtual event
_IEasyBridgeEvents_OnSetValueInCompositionEventHandler
OnSetValueInComposition;
public virtual event _IEasyBridgeEvents_OnTraceNotifyEventHandler
OnTraceNotify;

[DispId(4)]
public virtual void CreateComposition(string bstrSourceId, string
bstrParameterName, ENDATATYPE ENDATATYPE, int nLength);

namespace _EasyEdaBridge4
{
[ComVisible(false)]
[TypeLibType(16)]
public delegate void
_IEasyBridgeEvents_OnGroupParameterValueEventHandler(object
VarParameterValue);
}==> this code was also made by tlbimp
==> you can see the object of parameter, i also pass variant from com to c#.

i hope this is to help you.^^



Hi,
I'm currently involved in porting a ATL COM dll project to
C#. For compatibility reasons, the signatures of the functions in the
exported .TLB file should remain the same when ported to C#. For the
majority, this seems to be a smooth process.

However, two functions in the Old COM project seem to be giving me a
hard time during porting. One function WriteBytes() basically takes in
a BYTE array, and transfers the values in the array to the Serial
Port. Similarly, ReadBytes() takes a BYTE array as a parameter, and
copies the values read in from the Serial Port into the array.

The function signatures for the ATL COM project are as below...

HRESULT ReadBytes([in]VARIANT *varBuffer, [in]long lNoOfBytes,
[out,retval]long* lBytesRead);
HRESULT WriteBytes([in]VARIANT *varBuffer, [in]long lNoOfBytes,
[out,retval]long* lBytesWritten);

Internally, what the old project does is..
BYTE buffer[512];
long retval=0;

_variant_t *varBuffer = new _variant_t;
varBuffer->byref = buffer;

pSerialInterface->ReadBytes(varBuffer,512,&retval);


Since C# does not support the VARIANT datatype, I declared the
functions in C# as members of an interface that I implement, as below.
Int32 ReadBytes(ref Object pOb, Int32 lNoOfBytes);
Int32 WriteBytes(ref Object pOb, Int32 lNoOfBytes);

My problem is, how do I convert the Object reference properly, so that
I get the base addresses of the arrays being passed in as VARIANT *.

Please help me out here...

Thanks in advance,
Bharat.
 
Z

zorrothefox.groups

Hi,

I think I did not describe my problem well enough. Let me do so now.

1) I had an old ATL COM Project called SerialComm which basically
allowed me to access the serial port. The important function
signatures for the ATL COM project as described in the IDL file are as
below...

HRESULT SetCommParamValue([in] short shParamIndex,
[in]long lParamValue, [out, retval]BOOL* bReturn);
HRESULT FlushTxBuffer();
HRESULT FlushRxBuffer();

HRESULT ReadBytes([in]VARIANT *varBuffer, [in]long
lNoOfBytes,[out,retval]long* lBytesRead);
HRESULT WriteBytes([in]VARIANT *varBuffer, [in]long
lNoOfBytes, [out,retval]long* lBytesWritten);

2) Now I need to port this ATL Project into it's C# equivalent Class
Library. This necessarily means that the interface should remain
exactly the same. I am defining the functions in an interface ISerial
which I implement in a class called Serial. Once I regasm and gacutil
the resultant dll, The SerialComm dll now resides in the cache. If I
use OleView to view the dll exported functions, I should basically
see the same function declarations as the old ATL COM IDL file used to
display, since the Interface should remain the same. Now this is
mostly a straightforward process. However in the functions ReadBytes()
and WriteBytes(), the old function declarations accepted an [in]
VARIANT * pointer.

The equivalent for a VARIANT * in C# being ref Object, I used the same
and declared my C# functions as
Int32 ReadBytes(ref Object rObj, Int32 iNumBytes);
Int32 WriteBytes(ref Object rObj, Int32 iNumBytes);

When I compile, regasm and gacutil the above c# declarations, and open
the associated .tlb file, I see the exact same declaration as in point
no 1. i.e.,
HRESULT ReadBytes([in]VARIANT *varBuffer, [in]long
iNumBytes,[out,retval]long* pRetVal);
HRESULT WriteBytes([in]VARIANT *varBuffer, [in]long
iNumBytes, [out,retval]long* pRetVal);

However, now the trouble that I'm having is, in the function
definition, I need to read some bytes from the serial port and fill
in the array pointed to by rObj.

My question is, is it safe to explicitly typecast the ref Object rObj
to a Byte[] and then read in the values? One worry is about type
safety. For example, if the user passes me a wrong type of pointer,
how do I detect it? barring type safety, I was thinking of some code
along the lines below...

Int32 ReadBytes(ref Object rObj, Int32 iNumBytes)
{
try
{
Byte[] byArr = (Byte[]) rObj;
SerialPort sp = new SerialPort();
..
..
..
sp.Read(byArr,0,iNumBytes); //read from the serial port directly
into the buffer.
}
catch(Exception e)
{
.......
}
return iNumBytes;
}


Any comments on the safety of this code? Any suggestions on how to do
it better would be welcome :)

Thanks in advance,
Bharat.
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top