How to convert a Byte() to an IntPtr in VB

G

Guest

My application, written in .NET VB, tries to get a communication port handle
from a TAPI object with this code:

Dim vFileHandle As Byte() = appel.GetIDAsVariant("comm/datamodem")

The vFileHandle is supposed to be a file handle (an IntPtr, I suppose). How
can I convert this Byte() in this IntPtr ?
 
T

TDC

The Marshal class (in System.Runtime.Interop) has mothods to convert
(copy actually) to and from unmanaged memory. If you browse the
methods there, you'll quickly find what you are looking for in response
to this and your other similar posted question.

Tom
 
G

Guest

I have obtained the TAPI3 file handle with VB and C++ code, like this:

Dim vFileHandle As Byte() = appel.GetIDAsVariant("comm/datamodem")
Dim iFileHandle As IntPtr
iFileHandle = BytePtr2Handle(vFileHandle)

The C++ BytePtr2Handle() is :

__declspec(dllexport) HANDLE BytePtr2Handle(BYTE* p)
{
return *((LPHANDLE)p);
}

I'm certain it could be done, in a simpler way, in VB (without C++ code) but
I don't know how.
 
J

Jay B. Harlow

Serge,
Dim vFileHandle As Byte() = appel.GetIDAsVariant("comm/datamodem")
Why is GetIDAsVariant returning a Byte()? It appears that it really should
return a COM VARIANT, in the .NET world COM Variants are exposed as
System.Object.

As TDC suggested: System.Runtime.Interop.Marshal is your friend here. It has
methods to marshal (convert/translate) between the COM/C++ (unmanaged) world
& the .NET (managed) world... However it helps to define the methods &
interfaces that you use first, as P/Invoke (how you define the method) is
your first "defense" on converting unmanaged types.


FWIW The name GetIDAsVariant, suggests it returns a COM Variant, a Google
search reinforces this notion. I normally check www.pinvoke.net for the
correct definitions of unmanaged interfaces & methods that I want to use in
the managed world.
 
G

Guest

Jay,

You're right, GetIDAsVariant() returns a COM Variant in C++ exposed as a
System.Object in .NET. It appears that the type of this .NET object is
System.Array and that the type of each item of this array is a byte. This is
why I was trying to interpret it as an array of bytes (Byte()).

I found on the TAPI newsgroup that the correct way of getting the com port
handle in C++ from a ITLegacyCallMediaControl object (TAPI3 object) was
something like :

BSTR bstrComm = ::SysAllocString(L"comm/datamodem");
BYTE *pDeviceID;
DWORD dwSize;
ITLegacyCallMediaControl *pCallMediaControl;
...
HRESULT hr = pCallMediaControl->GetID(bstrComm, &dwSize, &pDeviceID);
HANDLE handle = *((LPHANDLE)pDeviceID);

So, in VB, it is:

Dim appel As ITLegacyCallMediaControl2
...
Dim obj As Object = callMediaControl.GetIDAsVariant("comm/datamodem")
Dim handle As IntPtr = Marshal.ReadIntPtr(obj, 0)

Thanks for your help.
 
J

Jay B. Harlow

Serge,
I would not expect a Handle to be returned as a Byte().

I would expect a Handle to be returned as an Integer...

How is your ITLegacyCallMediaControl2 defined?
 
G

Guest

Jay,

ITLegacyCallMediaControl2 is an extension of the ITLegacyCallMediaControl
which is one of the interfaces of the TAPI3 call object created when an
address connects to another one. GetIDAsVariant() is a method of the
ITLegacyCallMediaControl2 interface (in C++, it is
ITLegacyCallMediaControl::GetID()).

I don't understand either why the return of
ITLegacyCallMediaControl2::GetIDAsVariant() is so opaque. It seems like it's
a low level function.

Here are some pieces of the related code :

Dim tapi As ITTAPI
Dim adresse As ITAddress
Dim appel As ITBasicCallControl
Dim telephoneNumber as String

'Create the tapi object.
tapi = New TAPI
'Call Initialize before calling any other TAPI function.
Call tapi.Initialize()
...
'adresse is one of the tapi.Addresses
...
'create a data call to a phone number
appel = adresse.CreateCall(telephoneNumber,
TapiConstants.LINEADDRESSTYPE_PHONENUMBER,
TapiConstants.TAPIMEDIATYPE_DATAMODEM)
appel.Connect(False)
...
'gets the TAPI3 comm port name
Dim portName As Byte() =
appel.GetIDAsVariant("comm/datamodem/portname")
'portName has to be converted to a String, each byte becoming a Char
of the String

'gets the TAPI3 comm port handle
Dim obj As Object = appel.GetIDAsVariant("comm/datamodem")
Dim hPort As IntPtr = Marshal.ReadIntPtr(obj, 0)

'now, you can use this handle in Win32 WriteFile(), ReadFile() calls
...
 
J

Jay B. Harlow

Serge,
I know what it is. :-|

I wanted to see your VB.NET definition of ITLegacyCallMediaControl2!

I wanted to make sure you had that defined correctly...
 

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