VC6 ATL DLL interop with VB.NET

D

Dave

I have an existing VC6 ATL COM DLL. It has a number of methods within it
that take a byte array as the methods parameters. Here's what the IDL looks
like in the VC6 DLL:

[id(32), helpstring("method GetSystemConfig")] HRESULT GetSystemConfig([in,
out] SAFEARRAY(unsigned char) *pData, [out, retval] long *retval);

As you can see it is a byte array (SAFEARRAY)

In the VB.NET object browser the the prototype looks like this:

Public Function GetSystemConfig(ByRef pData as System.Array) as Integer

PROBLEM: Everyone of the API calls made in the following code section throws
an error:
"Specified array was not of the expected type. Err.Number = 5 "

I currently have VB.NET up in the VC 6 debugger just to see if the interface
ever gets called, and it does not. Which means my problem is in the interop
dll that Dot net creates automatically.

Public Function GetSystemConfig(ByRef pBytes As System.Array) As Integer
On Error GoTo processerror

Dim pByte() As Byte
GetSystemConfig = (ESITapi.GetSystemConfig(pByte) = S_OK)

Dim pByt(512) As Byte
GetSystemConfig = (ESITapi.GetSystemConfig(pByt) = S_OK)

Dim chars As Byte() = System.Text.Encoding.ASCII.GetBytes("hello
world")
GetSystemConfig = (ESITapi.GetSystemConfig(chars) = S_OK)

Dim arr As Array

GetSystemConfig = (ESITapi.GetSystemConfig(arr) = S_OK)

Dim strArr() As String = {"1", "2", "3"}
GetSystemConfig = (ESITapi.GetSystemConfig(strArr) = S_OK)

Dim pB(512) As Char
GetSystemConfig = (ESITapi.GetSystemConfig(pB) = S_OK)

End Function

Is there any way I can debug VB.NETS interop DLL ?
Any idea's what's wrong with the parameters I'm passing ?
FYI, I'm using VS 2005
This ATL control was written for use with VB6 and has been in production for
years, I'm trying to reuse it in the Dot Net world.
Anyone got any ideas ?

Dave
 
P

Peter Huang [MSFT]

Hi Dave,

From you description, I understand that you want to call ATL COM DLL in
VB.NET. The COM DLL has been working with VB6 well.
If I misunderstood, please feel free to let me know.

I think so far can you provide the some code about what will you do in the
method
[id(32), helpstring("method GetSystemConfig")] HRESULT GetSystemConfig([in,
out] SAFEARRAY(unsigned char) *pData, [out, retval] long *retval);

Also We have a wizard to upgrade VB6 application to VB.NET, I think you may
try to use that Wizard to upgrade VB6 program to VB.NET to see if that
works.

Please NOTE that may need some tweak after convertion.

You may have a try and let me know the result.

If you still have any concern, please feel free to let me know.
I look forward to hearing from you.

Best regards,

Peter Huang

Microsoft Online Community Support
==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
D

Dave

Peter,

I actually figured this problem out. It took me all day but I determined
that the SafeArray type that I assigned it in the code and the type that I
assigned to it in the IDL were different. This didn't cause any problems in
VB6 but in VB.NET and C# when used with the .Net interop dll it is a
problem.

I'm not using VB6, I'm using VB.NET, there is no problems using the DLL with
VB6 that's what it was initially used for. VB.NET and C# have problems with
this dll.

On another note, is there a way to debug the interop DLL ? Like generate a
project for it for debugging purposes ?

Here's what needs to be known by anyone that trys to do interop with an ATL
COM control with SafeArrays as parameters in methods. This code sample was
cut and pasted in but should provide a decent example.

[id(32), helpstring("method GetSystemConfig")] HRESULT GetSystemConfig([in,
out] SAFEARRAY(unsigned char) *pData, [out, retval] long *retval);

STDMETHODIMP CATLTapi::GetSystemConfig(SAFEARRAY **pData, long *retval)
{
SAFEARRAY* pAr = NULL;
SAFEARRAYBOUND rgsArrayBound[1];

rgsArrayBound[0].Lbound = 0;
rgsArrayBound[0].cElements = 50; // Array length
pAr = SafeArrayCreate(VT_UI1,1,rgsArrayBound);

// Pointer to the pAr's data section
LPVOID pV;
HRESULT RES;
RES = SafeArrayAccessData(pAr,&pV);

if(RES)
{
LogIt("OnDevSpecific() SafeArrayAccessData Error!");
break;
}


memcpy(pV,"12345678901234567890123456789012345678901234567890",50);

SafeArrayUnaccessData(pAr);

*pData = pAr;
.....


Dave
 
P

Peter Huang [MSFT]

Hi Dave,

From your description, you have resolved the issue, if I have any
misunderstanding please feel free to post here.
I know that your solution worked in VB6, because we can upgrade VB6 Project
into VB.NET project, so I suggest you have a try.

To debug an application, we need the symbols otherwisse we will only see if
the assembly code. Unfortunately , the IDE generated Interop Assembly
neither generated Symbols(commonly it is pdb file) nor source code. So we
can not debug into it.
But if you have both .NET client source code and C++ source code, we can
debug into the C++ code when we try to call into C++ aproach from .NET.


Best regards,

Peter Huang

Microsoft Online Community Support
==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 
D

Dave

I have already upgraded the VB6 project to VB.NET, but I still use it as a
reference point.

I know how to debug the C++ code, I actually launch VS 2005 from the VS 6
debugger.

It's too bad the interop can't be debugged seems like there could be some
value in that.
 
P

Peter Huang [MSFT]

Hi Dave,

As I said before, the IDE did not generate Symbol file and source file for
the Interop Assembly so the any debugger did not know that the code is.
If you do need to behavior, you have to create the Interop Assembly
manually so that it is a common class library coded by yourself.
How to: Create Wrappers Manually
http://msdn2.microsoft.com/en-us/library/x8fbsf00(VS.80).aspx

But we may still need the symbols for the CLR itself.

Commonly the IDE will generate correct Wrap assembly for us, if you did not
want the generated Assembly, we have to create one ourselves per the link
above.

Anyway, there is a detailed COM Interop Referece Book, you may have a check.
..NET and COM: The Complete Interoperability Guide (Paperback)
by Adam Nathan
http://www.amazon.com/gp/product/067232170X/103-1572468-9548663?v=glance&n=2
83155

If you still have any concern, please feel free to post here.

Best regards,

Peter Huang

Microsoft Online Community Support
==================================================
When responding to posts, please "Reply to Group" via your newsreader so
that others may learn and benefit from your issue.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.
 

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